接著上一篇?Apktool 源碼-反編譯 - 簡書?來說,這次接著說重新打包apk的流程。
1、重新打包
? ??private static void cmdBuild(CommandLine cli)
? ? 1、new了一個Androlib類,將apkOptions傳入,調(diào)用build方法時將反編譯的目錄appDir傳進去。 ? ?

? ? 2、常見的日志輸出 ? ?

? ? 3、解析apktool.yml文件

? ? ? ? ? ? yml文件里,是apktool進行反編譯時存儲的相關信息。重新打包要完全還原apk,必須要使用到這個文件。特別是里面的?doNotCompress 內(nèi)容,對于游戲包體來說,十分重要。
????????????MetaInfo類的字段內(nèi)容

4、準備相關目錄,開始進行打包


5、buildSources(appDir)
? ? 打包代碼,分為兩種情況,一種是反編譯的時候就沒有反編譯源代碼的。那么就是處理classes.dex文件,直接拷貝即可。
? ? 另一種是反編譯了代碼的,處理的是smali目錄下的smali文件。

6、buildNonDefaultSources
? ? 處理多個dex的情況下的smali文件,以smali_開頭的文件夾,以及.dex結(jié)尾的dex文件,處理方式同第5步.

7、buildManifestFile
? ? 處理AndroidManifest.xml,包括原始AndroidManifest.xml文件。若存在resources.arsc說明沒有反編譯資源,則無需處理AndroidManifest.xml文件,直接返回。否則,刪除原始AndroidManifest.xml,并開始處理AndroidManifest.xml文件。

? ? 其中fixingPublicAttrsInProviderAttributes方法,是修復provider節(jié)點中的@string字符串引用bug,這是AOSP中的一個bug。會導致應用安裝失敗,apktool使用具體的字符串值替換引用來避免此bug。
8、buildResources(appDir, meta.usesFramework)
? ? 方法中包含對資源和manifest的處理,其中都判斷了資源是否進行過修改,如果進行過修改,就會重新打包資源。其中manifest中的debug標記也是在這里設置的。當然,如果設置了進行強制全編譯,無論資源是否進行過修改,都會重新打包。

? ? 在buildManifest方法中可以看到,apktool使用aapt打包資源,而其中又分為appt1和aapt2打包兩種方式。此處其實有蠻多坑的,個人對于appt1和aapt2打包方式也有許多不甚解的地方,后續(xù)還要再研究,開帖詳述。


9、buildLibs
? ? 處理libs,此處的libs中只有so庫等資源了,jar這些早已在smali文件夾中了。簡單的拷貝即可,當然也包括了一些kotlin的東西。

10、buildCopyOriginalFiles
? ? 拷貝原始文件,如果original目錄存在,就拷貝其中的META-INF文件夾以及AndroidManifest.xml到apk中去。這個主要是看反編譯的時候的配置,是否存在original目錄來決定。

11、buildApk
? ? 最后打包apk,做Android的應該都知道,apk文件其實就是一個壓縮包,改個后綴為zip或者直接壓縮工具就能打開apk文件,這個操作就不多說了。
12、buildUnknownFiles
? ? 處理未知文件,即不屬于Android定義的部分文件。之所以用這種方式來處理,是因為aapt不能處理非Android定義的文件,因為aapt它不認這些文件。

13、再次處理AndroidManifest
? ? 前面的步驟把AndroidManifest.xml拷貝到了AndroidManifest.xml.orig,然后AndroidManifest.xml用來appt處理資源,現(xiàn)在再把AndroidManifest.xml.orig拷貝回來。

? ? 至此,打包結(jié)束。
? ? 最近在忙著處理一些自己的私活,時間變得不再充裕,寫文章的速度慢了好多。本篇文章的深度也是不夠的,個人完全能感覺出來,只能說后續(xù)看有沒有時間再深入分析吧。不過也理了個大概的流程,如果在使用apktool的過程中,遇到一些問題,倒也能進行一些修改,重新編譯,訂制自己的一個apktool了。勉強夠用吧。