前言
前端时间在学习Qigsaw相关的源码,思考到一个问题。动态加载的feature包里的资源id是否会与主包中的资源id冲突。因为主包的apk文件不一定是和加载的feature包是一起打包生成的,feature包是可以进行升级的。查看Qigsaw编译脚本对old.apk进行增量编译feature的时候也没有发现对R文件做特殊的处理。
那么Android怎么保证两次编译出的feature包中的资源id不与主包中的冲突呢?我们带着问题阅读文章进行答案的探索(Android中资源属于一个大模块,我们本地只讨论其中与R文件相关的部分)。
不同的android-gradle版本可能对R文件的格式以及生成目录会略作修改,本文只选了两个版本做参考。同步的反编译工具反编译出来的结果不仅相关,我们主要以AndroidStudio结果为主。
知识回顾
在代码中访问资源
您可以以方法参数的形式传递资源 ID,进而在代码中使用资源。例如,您可以设置一个ImageView,从而借助setImageResource()使用res/drawable/myimage.png资源:
ImageViewimageView=(ImageView)findViewById(R.id.myimageview);imageView.setImageResource(R.drawable.myimage);
您还可利用Resources中的方法检索个别资源,并且您可通过getResources()获得该资源的实例。
语法
以下是在代码中引用资源的语法:
[.]R..
是资源所在包的名称(如果引用的资源来自您自己的资源包,则不需要)。是资源类型的R子类。是不带扩展名的资源文件名,或XML 元素中的android:name属性值(若资源是简单值)。
其实到这里我们已经解决了我们阅读本文的目的。
主包的资源文件ID和feature包的资源文件ID值是由于不一致导致最后ID值不会相同。
有时间的小伙伴可以继续往下阅读,后面更精彩。
R文件
主工程R文件结构
插件的R文件结构
R文件中每个资源ID值一共4个字段,由三部分组成:PackageId+TypeId+EntryId
PackageId:是包的