微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – Android Instrumentation Testing – UI线程问题

我正在尝试为我的Android应用程序编写一个Instrumentation Test.

我遇到了一些奇怪的线程问题,我似乎无法找到解决方案.

我的原始测试:

@RunWith(AndroidJUnit4.class)
public class WorkOrderDetailsTest {

    @Rule
    public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.class);

    @Test
    public void loadWorkOrder_displaysCorrectly() throws Exception {
        final WorkOrderDetails activity = activityRule.getActivity();

        WorkOrder workOrder = new WorkOrder();
        activity.updateDetails(workOrder);

        //Verify customer info is displayed
        onView(withId(R.id.customer_name))
                .check(matches(withText("John Smith")));
    }
}

这导致了一个

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

com.kwtree.kwtree.workorder.WorkOrderDetails.updateDetails(WorkOrderDetails.java:155)

updateDetails()方法唯一做的就是调用setText().

经过一番研究,似乎在我的测试中添加一个UiThreadTestRule和android.support.test.annotation.UiThreadTest注释就可以解决问题.

@UiThreadTest:

@RunWith(AndroidJUnit4.class)
public class WorkOrderDetailsTest {

    //Note: This is new
    @Rule
    public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

    @Rule
    public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.class);

    @Test
    @UiThreadTest //Note: This is new
    public void loadWorkOrder_displaysCorrectly() throws Exception {
        final WorkOrderDetails activity = activityRule.getActivity();

        WorkOrder workOrder = new WorkOrder();
        activity.updateDetails(workOrder);

        //Verify customer info is displayed
        onView(withId(R.id.customer_name))
                .check(matches(withText("John Smith")));
    }
}

java.lang.IllegalStateException: Method cannot be called on the main application thread (on: main)

(注意:此堆栈跟踪中的所有方法都不是我的代码)

它似乎给了我混合的结果……如果它需要在创建视图但不能在主线程上运行的原始线程上运行,那么应该运行什么线程?

我真的很感激任何帮助或建议!

解决方法:

这些仪器测试在他们自己的应用程序内运行.这也意味着,它们在自己的线程中运行.

您必须将您的仪器视为与实际应用程序一起安装的内容,因此您可能的交互是“有限的”.

您需要从应用程序的UIThread / main线程调用所有视图方法,因此调用activity.updateDetails(workOrder);从您的检测线程不是应用程序主线程.这就是引发异常的原因.

你可以运行你需要在主线程上测试的代码,就像你在不同的线程中通过使用它在应用程序中调用它一样

activity.runOnUiThread(new Runnable() {
    public void run() {
        activity.updateDetails(workOrder);
    }
}

运行此测试应该可以正常运行.

您收到的非法状态异常似乎是因为您与规则的交互. documentation

Note that instrumentation methods may not be used when this annotation is present.

如果您在@Before中开始/开展活动,它也应该有效.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐