Android應用程序資源可以分為兩大類,分別是assets和res:
- Assets里面保存的是一些原始的文件。 根據文件名來訪問這些文件。
- res里面包含很多類型的文件,都需要根據Id來訪問。
通過ClassLoader 實現 Hotfix 可能存在的一個問題就是,兩次打包間資源ID很可能會發生變化。
比如打包前有一個String資源ID為0x7f050005。如果資源文件發生變化,比如我們在dev上新加了資源或者重命名了資源,即使不被當前Hotfix包含的Class所引用,也可能會導致問題,因為資源文件的ID可能發生了變化。
這幾天想通過Hack 打包中AAPT處理資源文件的過程來盡量保證多次打包過程中未發生變化的資源的ID盡量保持一致??傮w來說思路是對的,但是施行起來難度比較大。
-
Android打包過程中對資源文件的處理。
推薦這篇文章 。 偷張圖來表示以下aapt打包資源文件的流程:
資源文件打包流程 -
對以上流程了解后,發現在Add Resource Symbols階段會在 /app/build/symbols/release/ 下生成一個R.txt文件。 格式如下
int attr button_color_normal 0x7f010000 int attr button_color_pressed 0x7f010001 int attr navigation_bar_background 0x7f010002 int color black 0x7f040000 int color grey 0x7f040001 int color red 0x7f040002 int color user_center_button_normal 0x7f040003 int color user_center_button_pressed 0x7f040004 int color user_center_clickable_text_color 0x7f040005
預期是第一次打包后,緩存R.txt文件,然后第二次打包時,優先根據上次的R.txtl來設置ResourceID。
-
接下來就是定制Gradle task來滿足我們的需求了。但是難點在于我們必須要了解相關Gradle Task的邏輯,以便我們來做Hack,但是這方面相關的資料好少。以下是相關的Task(通過 -m 參數來獲取的)。
:app:prepareReleaseDependencies SKIPPED :app:mergeReleaseAssets SKIPPED :app:compileReleaseRenderscript SKIPPED :app:generateReleaseResValues SKIPPED :app:generateReleaseResources SKIPPED :app:mergeReleaseResources SKIPPED :app:processReleaseManifest SKIPPED :app:processReleaseResources SKIPPED
我正在嘗試下載Android Studio的源碼來查看這部分的具體邏輯。。。。。