Android应用程序资源可以分为两大类,分别是assets和res:
- Assets里面保存的是一些原始的文件。 根据文件名来访问这些文件。
- res里面包含很多类型的文件,都需要根据Id来访问。
通过ClassLoader 实现 Hotfix 可能存在的一个问题就是,两次打包间资源ID很可能会发生变化。
比如打包前有一个String资源ID为0x7f050005。如果资源文件发生变化,比如我们在dev上新加了资源或者重命名了资源,即使不被当前Hotfix包含的Class所引用,也可能会导致问题,因为资源文件的ID可能发生了变化。
这几天想通过Hack 打包中AAPT处理资源文件的过程来尽量保证多次打包过程中未发生变化的资源的ID尽量保持一致。总体来说思路是对的,但是施行起来难度比较大。
-
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的源码来查看这部分的具体逻辑。。。。。
网友评论