這篇文章是對菲姐這篇文章www.reibang.com/p/e1ce610788ea的思考以及衍生梭域。
這是我們目前的打包方案,將母包與QQ包打在一起
QQ登錄是第三方渠道先煎,以jar包提供給我們屯碴。jar包里面是不含有res資源的。這種方案中言缤,可以將qq的res直接拷貝到母包res中相應(yīng)的目錄下嚼蚀,比如qq中的QQ圖標(biāo),拷貝到res中的drawable中管挟,我們想要在重新打包后動態(tài)獲取到該圖像資源轿曙,只能采用getResources().getIdentifier()的反射方式,這種方式加載資源比較慢哮独,并且官方不推薦拳芙。而我們動態(tài)加載資源中另外一種反射的方式,資源加載比較快皮璧,具體代碼如下:
然后在需要加載該圖片的地方將該resID傳入就可以了舟扎。可以看到我們是直接反射到了R.java文件悴务,所以速度更快睹限。
很可惜,直接將res資源拷貝進(jìn)去讯檐,再次重新打包羡疗,我們沒辦法采用第二種反射方案,因?yàn)镽.java文件中沒有新加入資源的ID值别洪,無法找到資源叨恨。
那我們能不能在將res資源拷貝進(jìn)去后,利用aapt重新處理res資源生成新的R.java文件挖垛,替代原來的R.java文件痒钝,然后在重新打包呢?答案是可以的痢毒。具體操作看下面:
為此寫了一個(gè)demo先驗(yàn)證可行性送矩。
新建一個(gè)工程
這里面我們點(diǎn)擊按鈕打開一張圖片
這張圖片開始并不存在res中,直接運(yùn)行點(diǎn)擊是沒有圖片顯示的哪替。我們將apk反編譯后栋荸,重新加入到res中,將之前的R.java文件刪除,利用aapt對res進(jìn)行處理晌块,重新生成R.java文件爱沟,然后利用反射去R.java里面找對應(yīng)的資源ID,看能不能將圖片顯示出來摸袁。
第一步:利用apktool對app_bug.apk進(jìn)行反編譯:apktool.bat d -f app-debug.apk
res就是res資源钥顽,java文件全在smail文件中,里面有反編譯后的R.java文件靠汁,R開頭的都是
第二步:我們將R開頭的文件全部刪掉蜂大,然后將圖片拷貝到res目錄下的drawable中
第三步:然后利用aapt對res資源進(jìn)行處理:
aapt package -f
-M E:\test1\app-debug\AndroidManifest.xml
-I C:\Users\gzheshufan\AppData\Local\Android\Sdk\platforms\android-26\android.jar
-S E:\test1\app-debug\res
-J E:\test1\app-debug\smali
-m
會生成新的R.java文件:
點(diǎn)開后我們可以看到為我們新加入的資源生成了資源ID,matric_client_qq_channel_ic是圖標(biāo)的名稱
第四步:處理R.java文件蝶怔,生成class文件:javac E:\test1\app-debug\smali\com\gzheshufan\myapplication\R.java
第五步:將生成的class文件全部添加到文件夾all奶浦,將class文件夾進(jìn)行處理,生成all.jar文件:
命令是:jar cvf all.jar E:\test1\app-debug\smali\com\gzheshufan\myapplication\all
第六步:將all.jar文件轉(zhuǎn)為dex文件:d2j-jar2dex -f? E:\test1\all.jar -o classes.dex
第七步:將dex文件轉(zhuǎn)換為smali文件踢星,放入hsfSmali文件夾:java -jar E:\test1\baksmali.jar disassemble -o hsfSmail classes.dex
第八步:將新生成的smali文件拷貝到最初smali文件夾的位置澳叉,也就是apk反編譯文件夾里面,于是我們就完成了利用aapt去生成R.java文件去替換原來的R.java文件的作用沐悦。
最后:重新打包:apktool.bat b app-debug -o app-debug-u-u.apk
? ? ? ? ? ? ? ? ? 對齊:zipalign -v -p -f 4 app-debug-u-u.apk app-debug-a-u.apk
? ? ? ? ? ? ? ? ? 簽名:apksigner sign --ks E:\test1\MatrixClientKey.jks --out app-debug-final.apk app-debug-a-u.apk
然后將apk文件安裝在模擬器上運(yùn)行抱婉,我們看到了后來加入的圖片占哟,并且采用的方式不是getResources().getIdentifier(),而是通過反射直接去尋找R.java文件,直接獲得資源ID的方式惦界。
以上這種思路倾芝,就解決了母包想要有選擇性的打入資源的時(shí)候论衍,如何更快加載資源的問題堰燎。
同時(shí),如果第三方渠道提供給我們的是aar文件淆储,我們利用反編譯的方式將其打入母包時(shí)冠场,因?yàn)闆]有渠道包的R.java文件,渠道包對其自身資源的引用也會報(bào)錯(cuò)本砰,會提示找不到資源碴裙,同樣可以采取這樣的思路。下來再研究研究点额。
參考資料:java轉(zhuǎn)class以及重新生成R.java文件:www.cnblogs.com/gordon0918/p/5466514.html??blog.csdn.net/dexlins/article/details/71774569