Android测试源码集BuildConfig.java中R.style.AKTheme无法访问的问题
我之前也碰到过一模一样的坑,你的问题核心在于仪器化测试(androidTest)源码集有一套独立的R类,和主应用的R完全是两个东西。你在productFlavors里直接把R.style.AKTheme作为buildConfigField的值,这段代码会原封不动塞进测试模块的BuildConfig.java里,但测试的R类根本没有AKTheme这个样式的引用,自然就报解析错误了。
下面给你三个可行的解决方案,按推荐程度排序:
方案一:用Gradle资源引用语法自动生成ID(最推荐)
Gradle本身支持用@style/xxx的语法直接引用资源,它会在编译时自动把这个引用转换成对应的资源ID数值,不管是主应用还是测试的BuildConfig都会拿到正确的数值,完全绕开R类的冲突问题。
修改你Module级别的build.gradle里的productFlavors配置:
productFlavors { QA { buildConfigField 'int', 'APP_THEME', "@style/AKTheme" } Integration { buildConfigField 'int', 'APP_THEME', "@style/IntegrationTheme" // 不同风味可配置不同主题 } }
同步Gradle后,你会发现测试模块的BuildConfig里的APP_THEME直接变成了十六进制的资源数值(比如0x7f0b0001),而不是R.style.AKTheme的引用,解析问题自然就消失了。
方案二:在测试代码里直接引用主应用的BuildConfig
如果你不想改动Gradle配置,也可以在测试代码里跳过测试模块的BuildConfig,直接用主应用的版本。
假设你的主应用包名是com.your.app.package,在测试代码里这么写:
int appTheme = com.your.app.package.BuildConfig.APP_THEME;
这样测试代码就会使用主应用里已经正确解析的主题ID,完全避开测试R类的问题。
方案三:手动使用资源ID数值(仅应急用)
你可以先在主应用的R.java里找到AKTheme对应的数值(比如public static final int AKTheme = 0x7f0b0001;),然后把buildConfigField改成直接写这个数值:
buildConfigField 'int', 'APP_THEME', '0x7f0b0001'
这个方法能快速解决问题,但缺点很明显:后续如果添加、删除或修改资源,这个数值可能会变化,需要手动更新,维护成本很高。
内容的提问来源于stack exchange,提问作者Adnan Khan

