如果你用 apktoool 反编译过 apk 就知道,反编译后res/values 下有一个 public.xml 文件,内容如图

 
 

这个东西有什么用呢?

 
先从如何使用资源 ID 开始,在开发中我们通常使用 Resources.getXXX(resid) 来获取某个资源,传入的是 ID 这个 ID 定义在 R.XXX 类里面,R 类是编译器自动生成的,打开看知道
 
 
其实资源 ID 就是一个常量,对我们引用了某个ID,编译成 APK 之后,这个ID的值就固定了,
而 apktool 在重新打包 apk 的时候会对资源重新编译 (编译成 resources.arsc 你有zip打开 apk 看得到),编译资源的时候自然需要对所有资源ID进行重新编排(这是一个随机过程)试想假设原包里面 drawable/a.png id=0x7f020003 那么重新编排资源ID后就可能是 0x7f020004 又假设原包 0x7f020004 对应图片 b.png,那你重新打包后的 apk 当显示 a.png 的时候就会替换成 b.png,这还好不会出错,倘若生成的一个 id 原包不存在,那会导致程序崩溃的!
 
所以 public.xml 的作用就是把对象资源 ID 写死!
 
格式是 
<public type="资源类型" name="资源名" id="0x7f080000" />
 
如果你细心观察就会发现,id 都是 0x7f 开头紧接着后面两位 08 是独立于每种资源类型的,再后面的编码就是从 1 开始咯
 
public.xml 特殊用途:
<public-padding name="my_" end="0x7f02000f" start="0x7f020001" type="drawable" />
 
public-padding 顾名思义,留间距,为什么要留间距,这就涉及到一个深奥的问题了,可以应用在 主题、apk动态更新 领域,这个我们以后讨论
 
加了这个的效果就是在 R 里多了 my_1 ~ my_15 的资源ID,这些个资源ID空的,你去引用会找不到资源,如图:
 

Android中可以使用public.xml 来固定自己需要的ID,比如在插件化开发,或者notification 的Icon中。

但 android gradle plugin 从1.3.0开始就直接忽略了public.xml ,现在我们需要通过gradle脚本来修正:

  1. afterEvaluate {
  2. for (variant in android.applicationVariants) {
  3. def scope = variant.getVariantData().getScope()
  4. String mergeTaskName = scope.getMergeResourcesTask().name
  5. def mergeTask = tasks.getByName(mergeTaskName)
  6. mergeTask.doLast {
  7. copy {
  8. int i=0
  9. from(android.sourceSets.main.res.srcDirs) {
  10. include 'values/public.xml'
  11. rename 'public.xml', (i++ == 0? "public.xml": "public_${i}.xml")
  12. }
  13. into(mergeTask.outputDir)
  14. }
  15. }
  16. }
  17. }

项目地址:https://github.com/ceabie/AndroidPublicXmlCompat

这招使是从另一个项目里学来的,并根据gradle plugin做了优化:

https://github.com/limpoxe/Android-Plugin-Framework

最新文章

  1. 浅析SQL查询语句未显式指定排序方式,无法保证同样的查询每次排序结果都一致的原因
  2. EC笔记,第二部分:5.了解C++默默编写并调用哪些函数
  3. java程序员的技能要求
  4. Flex debug版本浏览器选定问题
  5. KTHREAD 线程调度 SDT TEB SEH shellcode中DLL模块机制动态获取 《寒江独钓》内核学习笔记(5)
  6. tomcat设置内存大小
  7. oracle学习 五 使用存储过程创建一个重置密码为123456的功能(持续更新中)
  8. 【转载】R6034错误,C Runtime Error
  9. php环境配置中各个模块在网站建设中的功能
  10. libvirtsAPI
  11. MonkenRunner通过HierarchyViewer定位控制的方法和建议(Appium/UIAutomator/Robotium侣)
  12. POJ1113 Wall 凸包
  13. [转载]C#控制台应用程序里调用自己写的函数的方法
  14. ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL&amp;EF
  15. 自动生成CHANGELOG.md
  16. CSS实现背景透明,文字不透明(兼容所有浏览器)
  17. 利用SparkLauncher 类以JAVA API 编程的方式提交Spark job
  18. 深入理解Spring的异步机制
  19. 10-string类的length()返回值一起的问题
  20. datagrid在MVC中的运用02-结合搜索

热门文章

  1. Julia - 字符串判断函数
  2. MonkeyScript测试命令集合
  3. postman 中url有动态变换的值时,可以按下面方式变换。
  4. git账户的存储
  5. memcached内存分配机制
  6. leetcode382
  7. 不可能的工作:在FBX模型导入脚本中生成模型的预置体
  8. VNC Linux 远程桌面控制软件
  9. mySQL中插入多条记录
  10. ZPP002M可重复执行