如果你用 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

Android R文件的id的更多相关文章

  1. android R文件不能识别?

    android R文件引入不了原因可能是: 1.xml有错误,导致R文件生成失败:(修改xml,并clear,然后再重新Bulid一下即可) 2.如果是图片,可能是命名有问题,查看并修改(不要以数字开 ...

  2. 关于Android Studio中的一个小问题——R文件引用Id失败

    错误情况: 今天使用AS建立了一个新的EmptyProject,结果出现错误 setContentView(R.layout.activity_main); R文件的引用Id失败.真的是莫名奇妙... ...

  3. Android R文件介绍

    R.java 文件中默认有attr.drawable.layout.string等色哥静态内部类,每个静态内部类分别对应着一种资源,如layout静态内部类对应着layout中的接界面文件,其中每个静 ...

  4. android R 文件生成不了

    在android中比较头疼的是R文件生成不了.今天总结一下R文件生成不了的一些原因和解决方法 1. xml文件有错, 如果在res文件中的xml文件有错,android不会自动生成R文件,此时仔细查看 ...

  5. android R 文件 丢失的处理 如何重新生成

    很多时候我们会遇到工程中的R.java文件丢失,必要急,修复很简单. 方法:右击你的工程(项目)——>Android Tools——>Fix Project Properties 即可. ...

  6. Android R文件相关问题

        今天遇到的问题,gen下没有自动生成文件,而大部分java文件中错误是找不到R.java.“R cannot be resolved to a variable” 这就一定有别的原因造成错误, ...

  7. 关于android R.layout 中找不到已存在的布局文件问题的解决

    今天遇到一个很奇怪的问题,打R.layout.,居然不会提示已经写好的布局文件,自己把xml文件名打下去后,居然提示错误. 开始以为是R文件中没有自动生成关于布局文件对应的整型,看了R文件,其实是有生 ...

  8. Andriod学习笔记2:“Your content must have a ListView whose id attribute is 'android.R.id.list'”问题的解决办法

    问题描述 activity_main.xml代码如下: <?xml version="1.0" encoding="utf-8"?> <Lin ...

  9. Android应用程序“.R文件”消失怎么办

    其实Android自己维护这一个 public final class R类主要是跟新资源文件,这个R.java无需我们自己去修改,如果你不了解千万不要去修改它,它定义的每个资源值都是唯一的,不会和系 ...

随机推荐

  1. 字体相关CSS属性介绍

    font-family 字体系列. font-family可以把多个字体名称作为一个“回退”系统来保存.如果浏览器不支持第一个字体,则会尝试下一个.浏览器会使用它可识别的第一个值. 简单实例: bod ...

  2. struts2的搭建和简单的例子(采用struts-2.5.2版本)

    struts框架的概述: 当2001年初,Struts的第一个版本在apache网站上发布,它提供了一种分离视图和业务应用逻辑的web应用方案. 在Struts诞生之前,开发人员都是在jsp里写入处理 ...

  3. Julia - 三元运算符

    三元运算符的格式: a ? b : c a 是条件表达式,如果条件 a 为真,就执行 b:如果条件 a 为假,就执行 c 二选一 julia> println(1 < 2 ? " ...

  4. <转>Python3.x和Python2.x的区别

    这个星期开始学习Python了,因为看的书都是基于Python2.x,而且我安装的是Python3.1,所以书上写的地方好多都不适用于Python3.1,特意在Google上search了一下3.x和 ...

  5. 13.solr学习速成之IK分词器

    IKAnalyzer简介 IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包. IKAnalyzer特性 a. 算法采用“正向迭代最细粒度切分算法”,支持细粒度和最大词长两 ...

  6. 来谈谈 WebAssembly 是个啥?为何说它会影响每一个 Web 开发者?

    作者:link 原文:What is WebAssembly and why it affects web developers! 你听说过WebAssembly吗?这是由Google, Micros ...

  7. Django xadmin的使用 (一)

    Django  xadmin的使用 xadmin是django的一个第三方的管理后台实现,它的功能比自带的admin功能更加强大. xadmin项目在github上的地址为:https://githu ...

  8. Spring Boot实践——Filter实现

    Filter介绍 Filter是Servlet规范规定的,不属于spring框架,也是用于请求的拦截.但是它适合更粗粒度的拦截,在请求前后做一些编解码处理.日志记录等. 一个Filter包括:1).在 ...

  9. mysql 随机查询 记录集

    有时候需求需要随机从数据库查询若干条记录集,网上搜了一下,几篇博文都是些重复的.....不知道他们谁抄的谁的,这里除了介绍提供一种笔者自己想到的方法,本质都是利用mysql 的rand() 第一种方法 ...

  10. then()方法是异步执行

    then()方法是异步执行 就是当.then()前的方法执行完后再执行then()内部的程序 这样就避免了,数据没获取到等的问题