《Android插件化開發(fā)指南》百度網(wǎng)盤pdf最新全集下載:

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比慶云網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式慶云網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋慶云地區(qū)。費用合理售后完善,十年實體公司更值得信賴。
鏈接:
?pwd=qn54 提取碼: qn54
簡介:本書不僅詳細介紹Android插件化技術(shù)如何實現(xiàn),而且包含大量Android系統(tǒng)的底層知識,有助于App開發(fā)人員深入理解Android系統(tǒng),從而寫出更健壯的代碼。 ?
前面插件化一和二說了下插樁式加載未安裝的APK,主要是重寫了getResource和getClassloader兩個方法來實現(xiàn)的。以及每個組件要實現(xiàn)一個接口,通過接口注入上下文來達到它的生命周期。
那么插樁式和hook式的實現(xiàn)方式有什么不同呢?
插樁式是怎么加載到插件中的class文件呢,是通過將將APK轉(zhuǎn)化成插件的Classloader,然后想要加載插件的class文件,我們的去拿這個插件的classloader去loadClass。所以是有一個中間者的。
hook式呢是將插件apk融入到了我們的宿主apk,那直接在里面就可以直接loadClass了,在不用這個插件的ClassLoader了,這樣的話對于插件和宿主就沒什么區(qū)別了,不像插樁式有一個中間者。
那么要實現(xiàn)hook式 就要知道android中一個class文件式怎樣被加載到內(nèi)存中去的。其實就是通過PathClassLoader來加載的。
那么我們先看下ClassLoader
任何一個java程序都是由一個或者多個class組成的,在程序運行時,需要將class文件加載到JVM中才可以使用,負責(zé)加載這些class文件的就是java的類加載機制。CLassLoader的作用就是加載class文件提供給程序運行時使用,每個Class對象內(nèi)部都有一個ClassLoader來標示自己是有那個classLoade加載的。
Android app的所有的java文件都是通過PathClassLoader來加載的,那么它的父類是BaseDexClassLoader,還有一個兄弟類是DexClassLoader,那么他們有什么區(qū)別呢。
從上面可以看出這兩個類的構(gòu)造函數(shù)不同。(在26的源碼中DexClassLoader中的optimizedDirectory也廢棄了)
PathClassLoader:用于Android應(yīng)用程序類加載器。可以加載指定的dex,以及jar、zip、apk中的classes.dex
DexClassLoader:加載指定的dex以及jar、zip、apk中的classes.dex。
可以看到創(chuàng)建ClassLoader的時候需要接收一個CLassLoader parent的參數(shù),這個parent的目的就在于實現(xiàn)類加載的委托。
某個類加載器在接到加載類的請求時,首先將加載任務(wù)委托給父類加載器,一次遞歸,如果父加載器可以完成加載任務(wù),那么就返回,只有當(dāng)父加載器無法完成加載任務(wù)時,才自己去加載。
因此我們自己創(chuàng)建的ClassLoader:newPathClassLoader("/sdcard/xx.dex",getClassLoader()),并不僅僅只能加載我們的xx.dex中的class。
需要注意的是,findBootstrapClassOrNull 這個方法,當(dāng)parent為null的時候,去這個BootCLassLoader進行加載,
但是在Android當(dāng)中的實現(xiàn):
所以new PathClassLoader("/sdcard/xx.dex",null),是不能加載Activity.class的。
上面分析了加載了一個class,是利用了雙親委托機制,那么要是都找不到那就開始調(diào)用自己的findCLass方法
在ClassLoader類中findClass:
任何ClassLoader的子類,都可以重寫loadClass和findClass。如果你不想使用雙親委托,就重寫loadClas修改實現(xiàn),重寫findClass則表示在雙親委托機制下,父ClassLoader都找不到class的情況下,定義自己去查找一個class。
而我們的PathClassLoader會自己負責(zé)加載Activity這樣的類,利用雙親委托父類去加載activity,而我們的PathClassLoader沒有重寫findClass,是在它的父類里面。因此我們可以看看父類的findClass是如何實現(xiàn)的。
可以看到加載PathClassLoader加載class,轉(zhuǎn)化為從DexPathList中加載class了,那么我們看看DexPathList中的findClass
那么從上面分析得到
到這里我們想要加載一個插件的apk ,其實最終加載的是一個dex文件(先說class文件,加載資源后面說),有沒有辦法吧這個dex文件給轉(zhuǎn)化成一個 Element 對象,給放到 Elemeng數(shù)組 當(dāng)中,這樣直接就可以加載我們插件中的類了。
1、首先我們肯定是要得到插件APK的的中DexPathList對象中的dexElement數(shù)組
2、插件的dexElements數(shù)組我們拿到了,那么是不是要開始拿我們系統(tǒng)里面的 ,我們反射獲取,和上面的一樣。
3、上面我們獲取到了系統(tǒng)和我們插件的dexElement數(shù)組,然后我們將這個數(shù)組合并到一個新的數(shù)組里面去,并且給注入到系統(tǒng)里面
至此,加載插件的一個流程基本就完成了。但是上面只是處理了class文件,沒有處理資源。資源的話我們也是采用hook的方式去實現(xiàn)
在宿主的Application中hook這個方法,然后去重寫getAsserts和getResources兩個方法:
然后在插件的BaseActivity中繼續(xù)重寫getAssets和getResources兩個方法
這樣就可以完成hook式加載一個未安裝的APK了。至此基本就完成了插樁式和Hook式插件化的基本實現(xiàn)。(后面幾篇是優(yōu)化)。
原理:實現(xiàn)原理上都選擇盡量少的hook,通過在manifest上預(yù)埋一些組件實現(xiàn)四大組件的插件化。其中Small更形成了一個跨平臺、組件化的框架。
VirtulApp:
能夠完全模擬app的運行環(huán)境,能夠?qū)崿F(xiàn)免安裝應(yīng)用和雙開技術(shù)。
Atlas:
阿里出品,號稱是一個容器化框架,結(jié)合了組件化和熱更新技術(shù)。
Android中有兩種類加載器,DexClassLoader和PathClassLoader,它們都繼承于BaseDexClassLoader。
兩者的區(qū)別:DexClassLoader多了一個optimizedDirectory的路徑參數(shù),這個目錄必須是內(nèi)部存儲路徑,用于緩存系統(tǒng)創(chuàng)建的Dex文件。
所以我們可以使用DexClassLoader去加載外部Apk中的類。
ClassLoader調(diào)用loadClass方法加載類采用了雙親委托機制來避免重復(fù)加載類。
首先,ClassLoader會查看自身已經(jīng)加載的類中是否已經(jīng)存在此類,如不存在,然后,則會使用父類來加載此類,如不能成功加載,則會使用自身重載于BaseDexClassLoader的findClass()方法來加載此類。
DexClass的DexPathList在DexClass的構(gòu)造器中生成,findClass()方法則是從DexPathList下面找出對應(yīng)的DexFile,循環(huán)DexElements,通過dexElement.dexFile取出對應(yīng)的DexFile,再通過DexFile.loadClassBinaryName()加載對應(yīng)的類。
作用:使用插件DexClassLoader加載出需要的類。
通過每一個插件的DexClassLoader加載出自身所需要的類,當(dāng)每一個插件需要加載相同的類庫時,可采用該類庫的不同版本來使用。
通過把每一個插件的pathList(DexFile)合并到主app的DexClassLoader上,來使各個插件和主app直接能夠相互調(diào)用類和方法,并且各個插件中相同的功能可以抽取出來作為一個Common插件供其它插件使用。
插件調(diào)用主工程
在ClassLoader構(gòu)造時指定主工程的DexClassLoader為父加載器即可直接調(diào)用主工程中的類和方法。
主工程調(diào)用插件
如果是多DexClassLoader的情況,則需要通過插件的DexClassLoader加載對應(yīng)的類并反射調(diào)用其方法。此種情況,主工程一般會在一個統(tǒng)一的地方對訪問插件中的類和方法做一些訪問權(quán)限的管理及配置。
如果是單DexClassLoader的情況,則可以直接調(diào)用插件中的類和方法。但是當(dāng)多個插件引用的庫的版本不同時,會出現(xiàn)錯誤,因此,建議采用Gradle版本依賴管理統(tǒng)一處理主工程及各個插件的庫依賴。
Android通過Resource來加載資源,只要有插件apk,就可以使用assertManager.addAssertPath(apkPath)的方式來生成assertManager,再使用其new出對應(yīng)的Resource對象即可。
注意:由于AssertManager并不是Public,所以需要通過反射的方式去調(diào)用它。并且由于一些Rom對Resource的處理,所以,需要兼容處理。
有2種處理方式:
產(chǎn)生的原因:由于主工程和各個插件引用的Resource id重復(fù)產(chǎn)生的沖突。
解決思路:Android中的資源在系統(tǒng)中是以8位16進制0XPPTTRRRR的方式存在,其中PP即是資源區(qū)分的區(qū)域(Android系統(tǒng)只用它來區(qū)分系統(tǒng)資源和應(yīng)用資源),只要讓每一個插件的PP段取不同的值即可解決資源id沖突的問題。
具體解決方式:
1.修改aapt源碼,編譯期修改PP段。
2.修改Resource的arsc文件,其中的每一條都包含了資源id和映射路徑。
Activity的處理最為復(fù)雜,有兩種處理方式:
1.ProxyActivity的方式。
2.預(yù)埋StubActivity,hook系統(tǒng)啟動Activity的過程。
原理:VirtualAPK通過替換了系統(tǒng)的Instrumentation,hook了Activity的啟動和創(chuàng)建,省去了手動管理插件Activity生命周期的繁瑣,讓插件Activity像正常的Activity一樣被系統(tǒng)管理,并且插件Activity在開發(fā)時和常規(guī)一樣,即能獨立運行又能作為插件被主工程調(diào)用。
Android插件化方向主要有2個方向:
Android 插件化
文章題目:android插件化,android插件化開發(fā)
URL網(wǎng)址:http://www.chinadenli.net/article46/dsdejhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、定制開發(fā)、關(guān)鍵詞優(yōu)化、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)