好久沒有寫博客了,這次準(zhǔn)備寫寫我這幾天的研究成果――Android插件化開發(fā)框架CJFrameForAndroid。
好久沒有寫博客了,這次準(zhǔn)備寫寫我這幾天的研究成果――Android插件化開發(fā)框架CJFrameForAndroid。
首先,你需要知道甚么是插件化開發(fā)。就拿最多見的QQ來講,在第3個(gè)界面動(dòng)態(tài)那里有個(gè)管理,點(diǎn)開后可以選擇很多的增植功能,這里騰訊只放了1些網(wǎng)頁利用,那末如果未來想加入1個(gè)打飛機(jī)游戲,要怎樣做?讓用戶重新安裝嗎,這就是插件化開發(fā)所解決的問題。
用1句話來概括插件式開發(fā):你基本上可以理解為讓1個(gè)apk不安裝也能夠被運(yùn)行。只不過這個(gè)運(yùn)行是有很多限制的運(yùn)行,所以才叫插件否則就叫病毒了。其實(shí)在目前淘寶、百度、騰訊、等都有成熟的動(dòng)態(tài)加載框架,包括apkplug,但是它們都是不開源的。
說1下我認(rèn)為這項(xiàng)技術(shù)的難點(diǎn):1、1個(gè)未被安裝的apk正常情況沒法被運(yùn)行;2、這個(gè)apk的資源沒辦法被援用;3、這個(gè)apk的界面就算被加載,也沒辦法與用戶交互。
最初查遍了資料,第1點(diǎn)好解決,在Android中有1個(gè)dexClassLoad類加載器,大家應(yīng)當(dāng)明白了,就是通過反射加載1個(gè)類來運(yùn)行。第2點(diǎn),網(wǎng)上有兩種方法:可以將插件的資源放到sd卡上通過流的情勢(shì)讀取,不過也有人反對(duì)說用流讀取會(huì)有問題,通配性太差;1種比較好的解決辦法是將apk中的資源復(fù)制1份到當(dāng)前app內(nèi),然后就能夠加載了。這類辦法是不錯(cuò),但是用戶每下載1次插件就復(fù)制1份,長此以往,對(duì)空間要求太高了,還有就是第3點(diǎn)也沒辦法解決。而第3點(diǎn),在github上有1個(gè)叫AndroidDynamicLoader的項(xiàng)目,是通過用Fragment做為插件的表現(xiàn)情勢(shì),由于Fragment特殊性(既可以處理邏輯交互又具有與Activity相同的生命周期)。可是Fragment限制性太大了,太過碎片化使得使用起來復(fù)雜性太高。直到我找到了1篇360的官方博客,博客給了1種思路:通過代理/拜托模式設(shè)計(jì)的Application類去動(dòng)態(tài)的改變1個(gè)apk所在的環(huán)境,實(shí)現(xiàn)動(dòng)態(tài)加載的目的。抱著這類思路,我曾想自己去設(shè)計(jì)1個(gè)application類,但是技術(shù)有限,太復(fù)雜了,因而結(jié)合AndroidDynamicLoader的思路與360的思路,我自己設(shè)計(jì)了1個(gè)Activity去代理插件的Activity,因而就有了CJFrameForAndroid.
首先解釋幾個(gè)名詞:
APP項(xiàng)目:指要調(diào)用插件apk的那個(gè)已安裝到用戶手機(jī)上的利用。
插件項(xiàng)目:指沒有被安裝且希望借助已安裝得手機(jī)上的項(xiàng)目運(yùn)行的apk。
插件化:Activity繼承自CJActivity,且與APP項(xiàng)目jar包沖突已解決的插件項(xiàng)目稱為已被插件化。
Activity事務(wù):在CJFrameForAndroid中,1個(gè)Activity的生命周期和交互事件統(tǒng)稱為Activity的事務(wù)。
托管所:指插件中的1個(gè)委派/代理Activity,通過這個(gè)Activity去處理插件中Activity的全部事務(wù),從而表現(xiàn)為就像插件中的Activity在運(yùn)行1樣。
CJFrameForAndroid的實(shí)現(xiàn)原理是通過類加載器,動(dòng)態(tài)加載存在于SD卡上的apk包中的Activity。通過使用1個(gè)托管所,插件Activity全部事務(wù)(包括聲明周期與交互事件)將交由托管所來處理,間接實(shí)現(xiàn)插件的運(yùn)行。
1句話描寫:CJFrameForAndroid中的托管所,復(fù)制了插件中的Activity,來替換插件中的Activity與用戶交互。
看到這里你應(yīng)當(dāng)就明白了,全部框架最核心的部份就是這個(gè)托管所。這里給出CJFrameForAndroid中這個(gè)托管所的細(xì)節(jié)代碼:
本框架目前僅僅是1個(gè)開發(fā)階段,僅僅是實(shí)現(xiàn)了插件Activity的運(yùn)行(原理上來講,動(dòng)態(tài)注冊(cè)的廣播也能夠運(yùn)行),而Service、contentProvider都沒辦法使用,這些都仍在研究中。
在未來的某1天,或許會(huì)將這個(gè)CJFrameForAndroid插件框架與KJFrameForAndroid快捷開發(fā)框架合并,組成1個(gè)更完善利用開發(fā)框架,對(duì)自己說:加油!
●目前僅支持Activity和Fragment,Service,動(dòng)態(tài)注冊(cè)的廣播,Activity LaunchMode,注解式開發(fā)。
●APP項(xiàng)目和插件項(xiàng)目中,都需要使用到CJFrameForAndroid的jar包。
●在項(xiàng)目中必須加入托管所聲明。
●在開發(fā)插件的時(shí)候,必須繼承CJActivity;
●在插件的Activity中,1切使用this的部份必須使用that來替換;
●在插件Activity跳轉(zhuǎn)時(shí),推薦使用CJActivityUtils類來輔助跳轉(zhuǎn);
●在插件和APP兩個(gè)工程中不能援用相同的jar包;