Android Instrumentation测试 - UI线程问题 [英] Android Instrumentation Testing - UI Thread Issues

查看:689
本文介绍了Android Instrumentation测试 - UI线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to write an Instrumentation Test for my Android app.

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

I'm running into some weird threading issues and I can't seem to find a solution.

我的原始测试:

@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:只有创建视图层次结构的原始线程才能触及其视图。

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)

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

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

The only thing the updateDetails() method does is some setText() calls.

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

After researching a bit, it seemed like adding a UiThreadTestRule and android.support.test.annotation.UiThreadTest annotation to my test would fix the problem.

@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:无法在主应用程序线程上调用方法(on:main)

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

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

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

It seems to be giving me mixed results... If it needs to be run on the original thread that created the views but can't run on the main thread, what thread should it be run on?

我非常感谢任何帮助或建议!

I'd really appreciate any help or suggestions!

推荐答案

这些检测测试在自己的应用程序中运行。这也意味着,它们在自己的线程中运行。

Those instrumentation tests run inside their own app. This also means, they run in their own thread.

你必须将你的仪器视为与实际应用程序一起安装的东西,所以你的可能的交互是有限的。

You must think of your instrumentation as something you install alongside your actual app, so your possible interactions are 'limited'.

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

You need to call all view methods from the UIThread / main thread of the application, so calling activity.updateDetails(workOrder); from your instrumentation thread is not the application main thread. This is why the exception is thrown.

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

You can just run the code you need to test on your main thread like you would do if you were calling it inside your app from a different thread by using

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

这个运行测试应该有效。

With this running your test should work.

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

The illegal state exception you are receiving seems to be because of your interaction with the rule. The documentation states


注意当存在此注释时,可能无法使用检测方法。

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

如果您在中开始/获取活动@Before 它也应该有效。

If you start / get your activity in @Before it should also work.

这篇关于Android Instrumentation测试 - UI线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆