一、Android插件化介紹
1.含義
所謂插件化,就是讓我們的應(yīng)用不必再像原來一樣把所有的內(nèi)容都放在一個apk中,可以把一些功能和邏輯單獨抽出來放在插件apk中,然后主apk做到[按需調(diào)用],這樣的好處是一來可以減少主apk的體積,讓應(yīng)用更輕便,二來可以做到熱插拔,更加動態(tài)化。
2.背景

3.優(yōu)點

二、Android插件化基礎(chǔ)
1.插件化的特點
- 應(yīng)用在運行的時候通過加載一些本地不存在的可執(zhí)行文件實現(xiàn)一些特定的功能;
- 這些可執(zhí)行文件是可以替換的;
- 更換靜態(tài)資源(比如換啟動圖、換主題、或者用服務(wù)器參數(shù)開關(guān)控制廣告的隱藏現(xiàn)實等)不屬于動態(tài)加載;
- Android中動態(tài)加載的核心思想是動態(tài)調(diào)用外部的 dex文件,極端的情況下,Android APK自身帶有的Dex文件只是一個程序的入口(或者說空殼),所有的功能都通過從服務(wù)器下載最新的Dex文件完成;
2.需要解決的問題
代碼加載
類的加載可以使用Java的ClassLoader機制,但是對于Android來說,并不是說類加載進來就可以用了,很多組件都是有“生命”的;因此對于這些有血有肉的類,必須給它們注入活力,也就是所謂的組件生命周期管理;
資源加載
資源加載方案大家使用的原理都差不多,都是用AssetManager的隱藏方法addAssetPath。
3.插件化必備基礎(chǔ)
①ClassLoader類加載器
要想實現(xiàn)加載外部dex文件(即插件)來實現(xiàn)熱部署,那么必然要把其中的class文件加載到內(nèi)存中。
其中涉及到兩種ClassLoader:DexClassLoader和PathClassLoader。而DexClassLoader可以加載外部的jar,dex等文件,正是我們需要的。
關(guān)于ClassLoader詳解,見ClassLoader完全解析。
②Java反射
因為插件apk與宿主apk不在一個apk內(nèi),那么一些類的訪問必然要通過反射進行獲取。所以了解反射對插件化的學習是必須的。
關(guān)于Java反射,見Java反射詳解。
③插件資源訪問
res里的每一個資源都會在R.java里生成一個對應(yīng)的Integer類型的id,APP啟動時會先把R.java注冊到當前的上下文環(huán)境,我們在代碼里以R文件的方式使用資源時正是通過使用這些id訪問res資源,然而插件的R.java并沒有注冊到當前的上下文環(huán)境,所以插件的res資源也就無法通過id使用了。
查看源碼,通過“addAssetPath”方法重新生成一個新的Resource對象來保存插件中的資源,避免沖突。
關(guān)于插件資源訪問,見使用插件中的R資源。
④代理模式
插件化實現(xiàn)的過程主要靠欺上瞞下,坑蒙拐騙來實現(xiàn)。想想雖然加載進來了Activity等組件,但也僅僅是最為一個對象而存在,并沒有在AndroidManifest中注冊,沒有生命周期的回調(diào),并不能實現(xiàn)我們想要的效果。因此無論是dynamic_load_apk通過代理activity來操控插件activity的方式,還是DroidPlugin通過hook activity啟動過程來啟動插件activity的方式,都是對代理模式的應(yīng)用。
關(guān)于代理模式,見靜態(tài)代理與動態(tài)代理。
至此,通過ClassLoader加載,然后通過代理模式讓Activity等組件具有生命周期實現(xiàn)真正的功能,并且解決了資源訪問問題??赡懿寮呀?jīng)可以簡單的實現(xiàn)一些初步的功能,然而插件化絕不止于此。更多的內(nèi)容仍需要進一步探索,不過以上知識是基礎(chǔ)中的基礎(chǔ),必備之必備。
三、Android插件化開源項目
介紹一下其中比較重要的兩個,實現(xiàn)思想不同,也是入門插件化可以學習的兩個。
Dynamic-load-apk
Dynamic-Load-Apk簡稱DL,這個開源框架作者是任玉剛,他的實現(xiàn)方式是,在宿主中埋一個代理Activity,更改ClassLoader后找到加載插件中的Activity,使用宿主中的Activity作為代理,回調(diào)給插件中Activity所以對應(yīng)的生命周期。這個思路與AndroidDynamicLoader有點像,都是做一個代理,只不過Dynamic-load-apk加載的插件中的Activity。
項目地址:https://github.com/singwhatiwanna/dynamic-load-apk
DroidPlugin
DroidPlugin是張勇實現(xiàn)的一套插件化方案,它的原理是Hook客戶端一側(cè)的系統(tǒng)Api。
項目地址:https://github.com/DroidPluginTeam/DroidPlugin
既然著重介紹了兩個項目,必然要學起來,怎么學習呢?
好在已經(jīng)有前人把自己的學習經(jīng)驗分享出來,那么我們只需要結(jié)合源碼進行學習即可。
四、Dynamic-load-apk詳解
Android插件化學習之路(一)之動態(tài)加載綜述
Android插件化學習之路(二)之ClassLoader完全解析
Android插件化學習之路(三)之調(diào)用外部.dex文件中的代碼
Android插件化學習之路(四)之使用插件中的R資源
Android插件化學習之路(五)之代理ActivityAndroid插件化學習之路(六)之動態(tài)創(chuàng)建Activity
Android插件化學習之路(七)之DL插件開發(fā)該注意的坑
Android插件化學習之路(八)之DynamicLoadApk 源碼解析(上)
Android插件化學習之路(九)之DynamicLoadApk 源碼解析(下)
五、DroidPlugin詳解
Hook機制之動態(tài)代理
Hook機制之Binder Hook
Hook機制之AMS&PMSActivity生命周期管理
插件加載機制
廣播的管理Service的插件化
ContentProvider的插件化
六、總結(jié)
以上內(nèi)容僅是Android插件化的入門知識,目前認知尚淺。
插件化、熱更新等技術(shù)在2016開始迅速發(fā)展,這即是業(yè)務(wù)發(fā)展的需求,也是我們需要緊跟前沿學習的技術(shù)。
參考文章:http://www.itdecent.cn/p/d9a823e94fb7
嗨~我是夏尼采,一個有夢想的IT男
每周輸出3篇有用的文章,目標是簽約簡書。
如果文章對您有幫助,希望能點個贊或者關(guān)注我。
您的關(guān)注和點贊是對我最大的鼓勵,感謝您的閱讀