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

设置requestedOrientation导致Android测试崩溃问题求助

问题:Jetpack Compose应用横竖屏切换测试崩溃

我正在测试一款基于Kotlin和Jetpack Compose开发的Android应用,验证横竖屏切换等配置变更场景,但设置屏幕方向为横屏/竖屏时出现崩溃。以下是简化的测试代码、应用代码及崩溃日志:

测试代码

package com.example.sandbox
import android.content.pm.ActivityInfo
import androidx.compose.ui.test.ComposeTimeoutException
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.core.app.ActivityScenario
import org.junit.Rule
import org.junit.Test

class MainActivityTest {
    @get:Rule
    val rule = createAndroidComposeRule<MainActivity>()
    private lateinit var scenario: ActivityScenario<MainActivity>

    @Test
    fun sandboxTest() {
        scenario = ActivityScenario.launch(MainActivity::class.java)
        rule.waitForIdle()
        rule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
    }
}

应用代码

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            SandBoxTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!"
    )
}

崩溃日志

java.lang.NullPointerException: Cannot run onActivity since Activity has been destroyed already
at androidx.test.internal.util.Checks.checkNotNull(Checks.java:50)
at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$androidx-test-core-app-ActivityScenario(ActivityScenario.java:792)
at androidx.test.core.app.ActivityScenario$$ExternalSyntheticLambda2.run(D8$$SyntheticClass:0)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:2497)
at android.os.Handler.handleCallback(Handler.java:984)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loopOnce(Looper.java:238)
at android.os.Looper.loop(Looper.java:357)
at android.app.ActivityThread.main(ActivityThread.java:8149)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)

问题原因与修复方案

崩溃原因

同时使用createAndroidComposeRule和ActivityScenario.launch()会导致重复启动Activity:

  • createAndroidComposeRule会自动初始化并启动指定的Activity实例
  • 手动调用ActivityScenario.launch()会再次启动新的Activity,原由Rule管理的Activity会被销毁
  • 后续调用rule.activity时,访问的是已被销毁的实例,触发NullPointerException

修复方案(推荐:保留Compose Rule)

移除手动的ActivityScenario相关代码,直接通过createAndroidComposeRule管理Activity:

package com.example.sandbox
import android.content.pm.ActivityInfo
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import org.junit.Rule
import org.junit.Test

class MainActivityTest {
    @get:Rule
    val rule = createAndroidComposeRule<MainActivity>()

    @Test
    fun sandboxTest() {
        rule.waitForIdle()
        // 通过Rule获取当前活跃的Activity设置方向
        rule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        // 可选:等待配置变更完成后执行后续操作
        rule.waitForIdle()
    }
}

替代方案(单独使用ActivityScenario)

如果需要更灵活的生命周期控制,可单独使用ActivityScenario,通过onActivity方法操作Activity:

package com.example.sandbox
import android.content.pm.ActivityInfo
import androidx.test.core.app.ActivityScenario
import org.junit.Test

class MainActivityTest {
    @Test
    fun sandboxTest() {
        val scenario = ActivityScenario.launch(MainActivity::class.java)
        scenario.onActivity { activity ->
            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        }
        // 等待配置变更完成
        scenario.waitForActivity()
    }
}

注意:此方式下无需使用createAndroidComposeRule,若需Compose UI测试,需结合对应API实现。


内容的提问来源于stack exchange,提问作者Saral

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:13:22