使用Room数据库开展单元测试时AS报NoSuchFieldError: useNoBackupDirectory错误
问题根本原因
- 该报错是类加载阶段版本错配引发的典型问题,核心诱因是Android Studio 4.1.2版本运行本地单元测试存在已知的类路径排序缺陷,和命令行Gradle构建的类加载逻辑不一致:
useNoBackupDirectory是AndroidX 1.5.0以上版本才新增的字段,Android SDK自带的无实际功能实现的旧版平台Stub包中不存在该字段。- 命令行执行单元测试时,Gradle会严格按照项目实际依赖树的顺序加载类,优先引入项目依赖的、包含目标字段的新版AndroidX组件,因此所有用例可以正常运行。
- Android Studio 4.1.2在运行单元测试时,会错误将平台Stub的旧版AndroidX关联类放到类路径最优先的加载位置,当Room内存数据库构建器尝试调用不存在的
useNoBackupDirectory字段时,就会抛出当前报错。
- 对应修复方式的生效逻辑:
- 用
testImplementation引入指定版本的SQLite依赖无法生效,是因为该范围引入的依赖仅会被分配到测试类路径的低优先级位置,无法覆盖被优先加载的平台Stub旧组件。 - 用
implementation引入指定版本的SQLite依赖可以修复问题,是因为该范围引入的依赖属于主源集类路径,优先级高于平台Stub包,会直接加载包含目标字段的新版SQLite组件,覆盖旧的Stub实现,最终消除报错。
- 用
相关官方说明
- Android Studio 4.1.x版本的已知问题清单中,明确记录了本地单元测试类加载顺序与Gradle构建规则不一致的缺陷,该问题在后续4.2及以上版本中完成修复。
- Room官方测试指南中提到,使用内存数据库开展本地单元测试时,需要保证androidx.sqlite、androidx.core的依赖版本和Room的传递依赖版本完全对齐,不能依赖平台Stub提供的旧版组件支撑测试运行。
内容的提问来源于stack exchange,提问作者Artur Latoszewski
相关产品推荐
相关产品推荐

