You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Android测试依赖后出现Activity已销毁相关异常求助

解决Robolectric&Espresso依赖升级后Activity场景已销毁的测试异常

问题背景

将测试依赖从旧版本升级到新版本后,原本正常的NfcCardReaderActivityTest测试用例出现异常:

  • 旧依赖:
// 旧依赖
testImplementation 'org.robolectric:robolectric:4.5-beta-1'
testImplementation 'androidx.test.espresso:espresso-core:3.4.0'
testImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
  • 新依赖:
// 新依赖
testImplementation 'org.robolectric:robolectric:4.14.1'
testImplementation 'androidx.test.espresso:espresso-core:3.6.1'
testImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
androidTestImplementation 'androidx.test:rules:1.6.1'

报错信息:

java.lang.NullPointerException: Cannot run onActivity since Activity has been destroyed already
错误发生在代码行:scenarioRule.getScenario().onActivity(activity -> {

同时伴随:

java.lang.IllegalStateException: Cannot move to state "RESUMED" since the Activity has been destroyed already

核心原因

  1. Robolectric 4.14.x版本对ActivityScenario的生命周期管理做了严格调整,相比4.5-beta-1版本,场景的销毁时机更早,且不允许在销毁后再操作Activity实例。
  2. AndroidX Test Rules 1.6.x与新版本Robolectric的集成逻辑变化,旧代码中直接获取scenario并调用onActivity的方式,可能在场景已进入销毁状态后执行。
  3. Espresso 3.6.x的内部生命周期同步逻辑与Robolectric的兼容性问题,导致Activity场景被提前终止。

解决方案

1. 规范ActivityScenarioRule的使用

确保每个测试方法使用独立的场景实例,避免跨测试复用:

@Rule
public ActivityScenarioRule<NfcCardReaderActivity> scenarioRule = new ActivityScenarioRule<>(NfcCardReaderActivity.class);

不要在@BeforeClass、静态代码块或测试方法外部操作scenario,所有场景操作都放在测试方法内部执行。

2. 调整onActivity的调用时机

在调用onActivity前,先确保场景处于活跃状态,主动将场景切换到RESUMED状态:

@Test
public void testNfcCardReading() {
    // 先将场景切换到活跃状态
    scenarioRule.getScenario().moveToState(Lifecycle.State.RESUMED);
    
    // 再执行onActivity操作
    scenarioRule.getScenario().onActivity(activity -> {
        // 你的测试逻辑
    });
    
    // 测试结束后无需手动销毁,Rule会自动处理
}

3. 改用生命周期回调监听操作

如果测试逻辑需要在特定生命周期状态下执行,使用场景的状态监听回调,避免直接在不确定状态下调用onActivity:

@Test
public void testNfcCardReading() {
    scenarioRule.getScenario().onStateChange(state -> {
        if (state == Lifecycle.State.RESUMED) {
            // 在Activity进入RESUMED状态后执行操作
            scenarioRule.getScenario().onActivity(activity -> {
                // 你的测试逻辑
            });
            // 监听一次后移除,避免重复执行
            scenarioRule.getScenario().removeOnStateChangeListener(this);
        }
    });
}

4. 清理依赖冲突

检查build.gradle中是否存在旧版本的AndroidX Test组件冲突,排除冗余依赖:

testImplementation('androidx.test.espresso:espresso-contrib:3.6.1') {
    exclude group: 'androidx.test', module: 'rules'
    exclude group: 'org.robolectric', module: 'robolectric'
}

同时添加必要的AndroidX Test适配依赖:

testImplementation 'androidx.test.ext:junit:1.1.5'
testImplementation 'androidx.test:core:1.5.0'

内容的提问来源于stack exchange,提问作者Sopnil.Shinde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:25:11