? ? ? ? 最近項(xiàng)目有一個(gè)需求捻悯,需要根據(jù)用戶(hù)需求動(dòng)態(tài)加載APP內(nèi)某功能模塊匆赃,且當(dāng)該部分功能模塊代碼有變動(dòng),只需更新該功能JAR今缚,無(wú)需更新整個(gè)APK算柳,基于這個(gè)需求,決定采用動(dòng)態(tài)加載Jar的方式去實(shí)現(xiàn)姓言,于是各種查資料進(jìn)行驗(yàn)證瞬项,終于搞定,由于最近腦子容量不夠何荚,所以將實(shí)現(xiàn)方式整理出來(lái)并開(kāi)放給大家進(jìn)行參考囱淋。
實(shí)現(xiàn)過(guò)程需要注意的點(diǎn):
1、當(dāng)我們實(shí)現(xiàn)功能的Library工程中還依賴(lài)了其他第三方Jar餐塘,我們需要將其合并妥衣,否則你生成的Library對(duì)應(yīng)的Jar包不含第三方文件會(huì)報(bào)錯(cuò);
2戒傻、Android的虛擬機(jī)(Dalvik VM)是無(wú)法識(shí)別Java打出jar的class文件税手,DVM識(shí)別的是dex文件,所以需要通過(guò)dx工具轉(zhuǎn)換成包含有dex文件的jar;
所以整個(gè)過(guò)程可以分為以下三個(gè)步驟來(lái)實(shí)現(xiàn):
第一步:創(chuàng)建Library工程需纳,導(dǎo)出Jar冈止;
第二步:將主Jar和依賴(lài)Jar進(jìn)行合并(ANT),將合并后的Jar進(jìn)行DX處理候齿;
第三步:利用DexClassLoader動(dòng)態(tài)加載熙暴;
下面通過(guò)一個(gè)例子來(lái)介紹具體實(shí)現(xiàn)闺属,首先看一下整個(gè)項(xiàng)目組成部分:
app:主工程Module;
commoninterfacelibrary:用于定義標(biāo)準(zhǔn)接口周霉,供主項(xiàng)目集成掂器,第三方實(shí)現(xiàn)具體功能;
dynamiclibrary:第三方實(shí)現(xiàn)功能庫(kù)俱箱,在主項(xiàng)目中国瓮,動(dòng)態(tài)加載該庫(kù);
utillibrary:工具庫(kù)狞谱,模擬動(dòng)態(tài)加載庫(kù)中引用的第三方類(lèi)庫(kù)乃摹;
一、生成Jar
1跟衅、在commoninterfacelibrary中定義通用接口及方法:
定義完成后孵睬,生成common_interface.jar;
注:生成jar包方法比較簡(jiǎn)單伶跷,直接Build——>Make Project后掰读,在build/intermediates/bundles/debug下找到classes.jar進(jìn)行重命名。
2叭莫、將common_interface.jar拷貝到dynamiclibrary項(xiàng)目app/libs下蹈集,然后在dynamiclibrary下的gradle中添加對(duì)此jar的依賴(lài):
定義ICommonInterface的實(shí)現(xiàn)類(lèi)DynamicImp并實(shí)現(xiàn)具體方法:
注:MathUtil是定義在utillibrary下的一個(gè)工具類(lèi),生成出common_util.jar后拷貝到dynamiclibrary進(jìn)行依賴(lài)雇初,此處實(shí)現(xiàn)比較簡(jiǎn)單忽略該步拢肆。
按照上面生成jar的方法,生成出dynamiclibrary對(duì)應(yīng)的dynamic.jar靖诗;
經(jīng)過(guò)上述步驟后郭怪,我們得到三個(gè)jar包,分別是:
common_interface.jar? 定義了標(biāo)準(zhǔn)接口呻畸;
common_util.jar 定義了工具類(lèi);
dynamic.jar 標(biāo)準(zhǔn)接口的實(shí)現(xiàn)類(lèi)悼院,我們需要?jiǎng)討B(tài)加載的jar伤为;
二、合并JAR并使用DX工具處理JAR包
? ? ? ? 下面我們開(kāi)始介紹合并Jar的流程据途,由于common_interface.jar是標(biāo)準(zhǔn)接口绞愚,我們會(huì)在主項(xiàng)目中引用,所以不需要合并它颖医,我們只需要合并common_util.jar和dynamic.jar位衩。
? ? ? ? 對(duì)于合并Jar的方式,網(wǎng)上有很多方式熔萧,如fatjar插件糖驴、或者用IDEA工具僚祷,具體操作方法自行百度,我這里用的是ANT合并的方式贮缕,首先我們需要安裝并配置ANT環(huán)境:
ANT下載官網(wǎng)地址:http://ant.apache.org/bindownload.cgi
下載完成后辙谜,解壓,然后在我的電腦 –> 右鍵屬性 –> 高級(jí)系統(tǒng)配置 -> 環(huán)境變量中配置ANT:
然后加入到系統(tǒng)變量的path中:
驗(yàn)證ANT環(huán)境是否已配置好:
看到上面的信息感昼,證明ANT配置成功装哆,下面來(lái)合并包,將需要合并的jar包放在同一個(gè)文件夾下定嗓,了解ant的都知道蜕琴,ant構(gòu)建的文件默認(rèn)為build.xml,所以在文件夾下我們還需要?jiǎng)?chuàng)建該文件宵溅,并進(jìn)行如下配置:
name? : 表示的是你即將合成的jar包的名字 凌简;
basedir :? 表示你存放jar包的目錄;
上面配置文件的含義就是层玲,將當(dāng)前目錄下所有jar進(jìn)行合并号醉,并在該目錄下載生成名字為dynamic_combine.jar的新包,文件配置好后辛块,執(zhí)行下面的命令:
執(zhí)行成功后畔派,我們需要將該jar包使用dx工具進(jìn)行轉(zhuǎn)化:
將合并后的jar包拷貝到android-sdk/buildtools下的任意一個(gè)版本目錄下,執(zhí)行“dx --dex --output=dynamic_combine_dx.jar dynamic_combine.jar”
三润绵、動(dòng)態(tài)加載
執(zhí)行成功后线椰,我們得到最終的dynamic_combine_dx.jar,下面我們可以在主項(xiàng)目中進(jìn)行動(dòng)態(tài)加載了尘盼,通過(guò)兩步來(lái)介紹動(dòng)態(tài)加載過(guò)程:
1憨愉、下載dynamic_combine_dx.jar到SD卡:
首先將dynamic_combine_dx.jar拷貝到app/assets下(這里是為了模擬下載過(guò)程,實(shí)際項(xiàng)目中可配置到后臺(tái)卿捎,從后臺(tái)下載)
注:需在manifest添加權(quán)限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2配紫、下載到SD卡成功后,進(jìn)行動(dòng)態(tài)加載調(diào)用相應(yīng)方法:
先執(zhí)行下載方法午阵,后執(zhí)行加載方法:
執(zhí)行結(jié)果為:
成功躺孝,撒花!5坠稹植袍!