Kotlin 切包適配實戰

做者

你們好,我叫小嘉; 本人20年本科畢業於廣東工業大學,於2020年6月加入37手遊安卓團隊;目前工做是國內遊戲發行安卓相關開發。java

問題背景

平常切包業務中,有的渠道 sdk 已經包含 kotlin 相關代碼。因爲以前沒有作 kotlin 的適配,致使在進行切包後的遊戲包進行閃退。markdown

平常切包業務如圖:函數

image.pngstyle="zoom:50%;"

觀察正常demo 包下面的資源狀況:測試

對比了切包後的遊戲包資源和正常 demo 包的資源,發現少了 kotlin 目錄,並且 META-INF目錄下也少了不少資源。優化

截圖.png

截圖1.png

文件根據目錄和後綴分爲四種:ui

.kotlin_module 位於 META-INF 目錄下 .version 文件位於 META-INF 目錄下 .kotlin_metadata 位於 kotlin 目錄下 .kotlin_builtins 位於 kotlin 目錄下spa

kotlin_module 文件

本質上是爲了優化頂級函數/變量定義時潛在的包名衝突,經過獨立的kotlin_module實現快速查找。另外一個是反射使用。3d

例如在kotlin中能夠書寫以下代碼,不指定類而直接建立一個包名頂級的函數code

截圖2.png

編譯後,與Java中以下寫法殊途同歸orm

截圖3.png

針對每一個lib/module生成kotlin_module文件,該文件的維度是以lib庫爲粒度,並非一個類一個文件 截圖4.png 若是再建立一個libkotlin,則kotlin_module會再增長一個 截圖5.png 除了開發者的kotlin模塊新增的文件,其餘都是kotlin庫產生的

在Demo測試中,刪除並無產生任何問題。這個配置是做用於編譯期,告訴編譯器如何正確生成class代碼的,運行期間並不會使用到,APK導包過程時能夠刪除。若是有使用kotlin reflect可能會出錯。

kotlin_metadata文件

二進制文件,從反編譯數據看,kotlin類通過編譯後,帶上了一個MetaData的註解,而且配置信息很是多,這也直接致使kotlin編寫的代碼生成的class文件,比java編寫的代碼生成的class要大。

截圖6.png

編譯後class

截圖7.png 這些元數據文件,在Demo中被刪除後程序正常運行,說明運行期間也沒有用上,可是不排除其餘反射調用會涉及。

kotlin_builtins文件

二進制文件,kotlin基礎庫的所支持的類庫新,若是刪除,反射實例化運行時就會直接報錯。 截圖8.png

.verison文件

純文本文件,內部通常是一個版本號。

截圖9.png

將demo 包體用 apktool 反編譯:

image10.png

image11.png

.kotlin_module 和 .version 在 original/META-INF 目錄下

.kotlin_metadata 和 .kotlin_builtins 位於kotlin目錄下

因爲切包業務是在中間層作的,因此最好作法是這些相關文件都保存

綜上所述kotlin 切包適配步驟:

一、反編譯生成渠道資源時,保留original目錄和META-INF目錄

二、合併渠道資源時,合併original和META-INF目錄

三、回編譯前刪除掉META-INF中的簽名文件

四、回編譯時 java -jar apktool.jar -c b xxx。新增-c參數 -c 參數的意思是保存 original 目錄

五、保存 kotlin 目錄

詳細步驟:

  1. 保留 kotlin 目錄

apktool 反編譯後會保存的目錄:kotlin 目錄是會存在的

wps7F0A.tmp.jpeg

這個2.4.1版本 apktool 裏面保留的正常目錄,因此假如反編譯存在 kotlin 目錄須要進行保留。

  1. 保留 orignal 目錄

original 目錄下保存的內容:

image12.png AndroidManifest.xml 和 META-INF(簽名文件) 此處只須要保存 META-INF 目錄。 注:假如 Original 目錄下存在 AndroidManifest.xml 的話,在會編譯的時候便會以此清單文件來進行回編譯,而不會以直接目錄下的AndroidManifest.xml 來回編譯

image13.png

  1. 保留 META-NIF目錄

  2. 處理 簽名文件(放在 Original/META-INF目錄裏面,因此須要刪除簽名文件,從新生成,若是不刪除 RSA / MF/ SF 簽名文件,此時是回編譯前的簽名文件,由於前面已經改過 apk 包文件, 會回編譯報錯)

build/apk 文件夾是用來生成 apk 的目錄,內容以下:

image15.png

相關文章
相關標籤/搜索