登录

去注册

登录

注册

去登录

注册

每日一问 这么多R.java 有卵用呀?

xiaoyang   2019-11-03   收藏

现在一个稍微大点的项目都几十个module,然后各种分层,下面我要举个例子:

A模块:com.zhy.A;
B模块:com.zhy.B;

A 依赖 B。

现在B里面有多个资源,那么在B中可以通过com.zhy.B.R.资源种类.资源名称访问。

其实B中的资源,在A中也能通过:

com.zhy.A.R.资源种类.资源名称访问。

那么一个资源,其实就在两个module中重复定义了。

一个非常大的项目,可能一个资源最终会被重复定义几十次,务必会造成apk体积增加。

那么问题是:

  1. 为什么要重复定义?讲道理你也可以直接访问依赖module里面的R呀。
  2. 如果确实造成包体积增加,可以去掉重复的,来缩小包体积吗?怎么做?
2

先回答一下第一问。

如果之前阅读过每日一问 关于 R.java 的生成规则,你知道多少? 这个问答,就会知道,在不同的 module 下,资源都是有序生成 id的,如果不合并生成,那么不同的 module就会生成相同的 id,而指向不同的资源,最终打包的时候就会纠结了。

其实这个还引申出一个问题,就是我们之前问的,为什么 lib module 下的R 里面的 id都不是 final 的? ,如果为 static final 的,会导致在 javac 阶段常量会被直接内联到代码(.class)中,而且这个内联几乎没有痕迹,这样合并资源重新生成新的 id 的时候,完全没办法替换已经被内联的 id。

第二问,我决定再等等大家来回答~~

回复
nanchen2251 : @鸿洋 

哈哈哈,不回答第二问,有卵用呀?

2019-11-01 回复
1

我们以前也为这个烦恼,后来就创建了个module叫ResCommon,里面没有java文件,只有res文件,就和JavaCommon一样,里面没有res文件,只有java文件。

res/values/下是可以创建多个string.xml文件的,一个strings.xml对应了一个module。

这样其实什么问题也没解决,只是新建资源的时候之前的资源存不存在更好找一点。

资源是资源值重复,这就涉及到资源命名问题,较多的是color命名,string命名大家都知道,一般都是把中文翻译过去英文就是名。

color命名就千奇百怪了,有人按功能命名,就出现了colorLogin这种。color也可以采用翻译命名,比如常见的black,white。很多颜色也不是谁都知道那是什么色,命名成color_123456,color_ababab就可以了

回复
0

如果确实造成包体积增加,可以去掉重复的,来缩小包体积吗?怎么做?

如果不同module之间同名的资源,那么在打包,合并资源的时候会根据module的优先级取同名资源的其中一个,同名的其它资源并不会打包到APK中(可参考:项目中同名资源,会不会覆盖,规则是怎么样的?)。
这样的话,也不会存在体积增加的问题。


但如果同一个资源,它们的名字不同,而且散落在不同module之间的话,确实会同时被打包进APK中,造成安装包体积增加。
这种情况的话,我觉得需要有一个工具来遍历各个module下的资源,通过MD5来检测出相同的资源,然后移除掉吧,当然了,也要对应地替换掉代码中引用到的资源名。
但是现在好像没有现成的工具。。。


“重复定义” ,如果说的只是R.java中的变量重复定义,不是说存在相同的资源文件的话,那我觉得也不用担心吧,因为这些id在打包时会合并(过滤重名),而且会重新分配值的。

回复
0

因为如果不这样做,会导致一个问题,就是A模块用B模块的资源的时候,使用的是B模块的R,然后那个资源做使用的资源ID,可能在A的R文件里以及有了,那么这个时候这个资源id是指向谁?

回复
0

赞成楼上

回复

删除留言

确认删除留言,会导致相关评论丢失?

取消 确定