使用 Espresso 规则时,无法在 Activity 的方法 finish() 中执行 UI 工作?
Can not do UI work in method finish() of Activity when using Espresso rules?
我正在使用 Espresso 为我的 Android 应用做 UI 测试。
按照官方指南,我使用 ActivityTestRule 启动了 Activity 待测。但是当测试完成时,发生了崩溃。
堆栈跟踪是
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
at android.view.ViewRootImpl.playSoundEffect(ViewRootImpl.java:5222)
at android.view.View.playSoundEffect(View.java:17876)
at android.view.View.performClick(View.java:4755)
at com.example.android.activityinstrumentation.ReadExternalFileActivity.finish(ReadExternalFileActivity.java:196)
at android.support.test.rule.ActivityTestRule.finishActivity(ActivityTestRule.java:234)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:259)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
抛出调用栈,我发现AndroidJunitRunner试图从非UI线程调用Activity的finish(),导致崩溃。
我的应用重写了 Activity 的 finish() 方法,弹出一个对话框询问用户是否确认退出,应该在 UI 线程上执行。
这是否意味着,在使用 Espresso 时,我无法在 Activity 的 finish() 方法中执行 UI 工作?或者这是 Espresso 的错误?
不要在 finish() 中做 UI 工作。
finish() 不是为了这个目的。 finish() 是用户对该对话框说“是”后发生的事情。
Activity 到达时应该已经从屏幕上消失了。我真的有点惊讶它需要一个测试用例才能看到失败。
您可以在 finish()
上进行 UI 操作,通常它仅用于关闭最后一个对话框、光标等,您也可以在 onDestroy
上进行操作.
没有一些代码摘录,我无法判断您的代码中是否存在错误。我的建议是将确认对话框移动到 onBackPressed
,只需添加对话框,当用户确认 he/she 想要退出时调用 super.onBackPressed()
否则不要这样做任何东西。
我正在使用 Espresso 为我的 Android 应用做 UI 测试。
按照官方指南,我使用 ActivityTestRule 启动了 Activity 待测。但是当测试完成时,发生了崩溃。
堆栈跟踪是
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
at android.view.ViewRootImpl.playSoundEffect(ViewRootImpl.java:5222)
at android.view.View.playSoundEffect(View.java:17876)
at android.view.View.performClick(View.java:4755)
at com.example.android.activityinstrumentation.ReadExternalFileActivity.finish(ReadExternalFileActivity.java:196)
at android.support.test.rule.ActivityTestRule.finishActivity(ActivityTestRule.java:234)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:259)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
抛出调用栈,我发现AndroidJunitRunner试图从非UI线程调用Activity的finish(),导致崩溃。
我的应用重写了 Activity 的 finish() 方法,弹出一个对话框询问用户是否确认退出,应该在 UI 线程上执行。
这是否意味着,在使用 Espresso 时,我无法在 Activity 的 finish() 方法中执行 UI 工作?或者这是 Espresso 的错误?
不要在 finish() 中做 UI 工作。
finish() 不是为了这个目的。 finish() 是用户对该对话框说“是”后发生的事情。
Activity 到达时应该已经从屏幕上消失了。我真的有点惊讶它需要一个测试用例才能看到失败。
您可以在 finish()
上进行 UI 操作,通常它仅用于关闭最后一个对话框、光标等,您也可以在 onDestroy
上进行操作.
没有一些代码摘录,我无法判断您的代码中是否存在错误。我的建议是将确认对话框移动到 onBackPressed
,只需添加对话框,当用户确认 he/she 想要退出时调用 super.onBackPressed()
否则不要这样做任何东西。