在java開發中隨處可見使用jar包的插件機制進行開發,但在android中,目前較成熟的插件機制基本沒有,看到的有兩篇帖子中提到了重寫dexclassloader可以完美的解決插件問題,但都只簡要描述了原理,沒有源碼或關鍵代碼,目前對網絡中的思路進行總結.
目前插件包有兩種格式:一種是apk,一種是dex包.對插件的接入機制來說也有兩種:一種是需要安裝,一種是不需要安裝.結合插件包的格式來說插件的方式只有三種:1,apk安裝,2,apk不安裝,3,dex包.三種方式其實主要是解決兩個方面的問題:1,加載插件中的類,2,加載插件中的資源.第一個加載類的問題,這三個方式都可以很好的解決.但目前三種方式都沒有很完美的解決第2個問題.下面分別總結下這三種方式網絡上和自己實踐出來的一些結論:
1,apk安裝方式.插件apk安裝后,可以在主程序中通過包名加載到插件的context,有了插件的context就可以解決加載插件資源的問題.但出現的新問題是:如果插件a,b,c間公用一個底層jar包,那么在abc間傳送數據時,需要進行序列化和反序列化,因為a中jar包的data類與b中jar包的data類雖然都是同樣的jar包也是同樣的類,但兩個類在java機制來是由不同的classloader加載的,是不同的類.那么就會出現插件間jar包冗余和數據傳遞的效率不好問題.總之能解決問題.
2,apk不安裝,這個是不推薦的方式.可以通過dexclassloader加載到插件a中的類,但插件沒有安裝就無法獲得插件apk的context,也就無法加載到資源,網絡上有牛人通過將主程序的context替換關鍵的對象(如classloader,assertmanager等),偽造成插件的context,然后通過偽context也可以獲得插件資源.目前個人驗證的問題為:獲取到的layout資源中的textview顯示文本有問題,無法顯示在layout設定的文本.同時個人猜測這種hack的方式或許有其它的未知的問題,但不排除高手已經解決了這個問題.
3,dex包,這個基本是java開發中jar包的方式.同樣通過dexclassloader加載到插件中的類,但依舊沒有context,也無法加載到資源.要使用布局,只能在插件中使用java代碼來寫布局.這種方式最簡單(1,類似jar包的方式,也可以隨意導出單個類的jar包然后轉化為dex包,不存在打包成apk需要完整的工程和依賴關系的要求.2,底層的公用jar包所有插件可以公共一個,傳遞數據不用反復的序列化和反序列化.),也是最復雜的(布局文件全部代碼寫,難調試,難維護).
參考資料:
1,android-application-plug-ins-frame-work
https://code.google.com/p/android-application-plug-ins-frame-work/
2,Android動態加載代碼技術
http://www.cnblogs.com/frydsh/archive/2012/12/21/2828561.html
3,Android基於類裝載器插件架構的實現 http://wenku.baidu.com/link?url=zrm8bGJeYOE5Z3REHLSITdGI28g-1jz2Kw_QWqWrFDHHRGnZq2W_Y3olKe5scn7ysD77Mw8INWfAtQshYKoD-9AdPgeSQgK5dnvIwU_YzbW
4, Android動態加載(上)——加載未安裝APK中的類
http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html
http://www.cnblogs.com/over140/archive/2012/03/29/2423116.html
5.Android Dynamic Loader框架(https://github.com/mmin18/AndroidDynamicLoader)
6,安卓應用程序插件化開發框架 -AAP Framework https://code.google.com/p/android-application-plug-ins-frame-work/
7,XCombine https://github.com/wyouflf/xCombine