插件化研究之资源冲突

作者: 大利猫 | 来源:发表于2016-04-09 21:59 被阅读965次

    最近在研究Android应用的插件化开发, 插件化都是在解决以下几个问题:

    本章我们来研究最后一个问题:资源共享与冲突。在《Android应用程序插件化研究之AssertManager》中,我们实现了加载插件apk中资源问题,实际上我们是单独创建了用于访问插件资源的AssertManager和Resource对象,即,插件独立使用一个资源管理器,这样插件宿主之间无法共享资源。

    资源共享

    如果需要宿主、插件之间使用同一套资源管理器,那么我们需要将插件的资源路径添加到宿主的AssetManager中。

    我们知道,apk包括代码和资源,在apk编译过程中,dex工具将代码打包成.dex文件,资源文件会由aapt工具生成对应的ID,aapt在打包的时候组织成resources.arsc文件(详细参考: Android应用程序资源的编译和打包过程分析),resources.arsc文件是用来描述资源ID和资源位置配置信息,从18个维度描述了一个资源ID的配置信息(语言、分辨率等),就是资源ID和资源的索引表。资源的ID生成是有规则的,规则:0xPPTTNNNN,由8位16进制组成,其中:
    PP段:表示资源的包空间:0x01表示系统资源空间,0x7f表示应用资源空间。
    TT段:表示资源类型。
    NNNN段:4个16进制表示资源id,一个apk中同一类型资源从0000开始递增。
    例如:

    nt anim pop_dialog_in 0x7f040000
    int anim pop_dialog_out 0x7f040001
    int anim slide_left_in 0x7f040002
    int anim slide_left_out 0x7f040003
    int anim slide_right_in 0x7f040004
    int anim slide_right_out 0x7f040005
    int anim update_loading_progressbar_anim 0x7f040006
    int array indicator_tab_icon 0x7f050001
    int array indicator_tab_titlt 0x7f050000
    

    现在问题来了,宿主apk和插件apk是独立编译出来的两个独立的apk,那么其中就有资源ID相同的情况出现,从而产生资源ID冲突。如何解决这个问题?看了一些开源框架,解决的办法就是修改资源ID的PP段,大体有两种做法:

    修改aapt源码,定制aapt工具编译期间修改PP段。

    DynamicAPK的做法就是如此,定制aapt,替换google的原始aapt,在编译的时候可以传入参数修改PP段:例如传入0x05编译得到的资源的PP段就是0x05。个人觉得这个做法不是太灵活,入侵了原有的开发编译流程,不好维护。

    修改aapt的产物,即,编译后期重新整理插件Apk的资源,编排ID。

    前面说过apk编译之后会生成ID以及对应的索引表resorce.arsc,那么我们能不能后期修改相关ID及索引表呢?答案是肯定的,个人比较赞同这种思路,不用入侵原有编译流程。

    结尾

    插件系列文章到此结束了,如果你从第一章开始看到此处,你应该明白插件化要解决的问题、实现的思路、要掌握的技术,如果你理解完这5篇文章,你应该有能力写出一个简单的插件方案了。文章重在点明思路,实践才是最重要的,关于实践我们要做的还有很多很多。

    相关文章

      网友评论

      • ecd7a169b709:如果我是用的是安装后的apk进行得到其package context,然后通过context.getResource来得到Resource对象,通过这个新生成的Resource对象来获取资源也会冲突吗?

      本文标题:插件化研究之资源冲突

      本文链接:https://www.haomeiwen.com/subject/ijrblttx.html