为什么Android应用依赖的部分库模块字符串无法通过应用R类直接访问
问题原因说明
该问题的核心来自Android Library模块的资源可见性规则和R类生成机制,具体原因如下:
- R类独立生成逻辑
每个Android模块(主应用、所有Library库)都会生成独立的R类,生成路径和模块自身的包名(AGP 7.0+对应build.gradle中的namespace配置)完全对应。默认情况下主应用的R类会合并所有依赖库的公开资源ID,因此可以直接通过主应用的R类访问大部分库资源。 - Library私有资源限制
Android Gradle 3.0及以上版本支持Library模块配置私有资源:如果libraryB在res/values/public.xml中显式声明了公开资源列表,未被声明的资源会被标记为私有,不会合并到主应用的R类中,直接调用主应用的R.string.stringLibB就会报找不到符号的错误。
而直接通过libraryB包名前缀引用com.package.libraryB.R.string.stringLibB可以正常访问,是因为每个库自身的R类会包含自身所有资源的ID,不受私有资源规则限制。 - 特殊场景:资源名冲突覆盖
如果libraryB没有配置私有资源,可以排查是否存在资源名冲突:如果主应用、libraryA中存在和stringLibB完全同名的字符串资源,资源合并时优先级更高的资源(主应用优先级最高,同是依赖库时后声明的优先级更高)会覆盖libraryB的同名资源,也可能导致主应用R类中不会生成对应ID。
可选解决方法
如果需要在主应用中直接通过主R类访问该资源,可以二选其一处理:
- 在libraryB的
res/values/public.xml中把stringLibB添加到公开资源列表 - 保持现有写法,直接通过libraryB的包名前缀引用其R类下的资源
内容的提问来源于stack exchange,提问作者Ashish Gupta
相关产品推荐
相关产品推荐

