Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android工具测试-UI线程问题_Java_Android_Multithreading_Testing_Junit - Fatal编程技术网

Java Android工具测试-UI线程问题

Java Android工具测试-UI线程问题,java,android,multithreading,testing,junit,Java,Android,Multithreading,Testing,Junit,我正在尝试为我的Android应用程序编写一个仪器测试 我遇到了一些奇怪的线程问题,似乎找不到解决方案 我的原始测试: @RunWith(AndroidJUnit4.class) public class WorkOrderDetailsTest { @Rule public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.

我正在尝试为我的Android应用程序编写一个仪器测试

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

我的原始测试:

@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")));
    }
}
@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)上调用方法

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

它似乎给了我复杂的结果。。。如果它需要在创建视图的原始线程上运行,但不能在主线程上运行,那么它应该在哪个线程上运行


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

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

您必须将您的工具视为与实际应用程序一起安装的东西,因此您可能的交互是“有限的”

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

您只需在主线程上运行需要测试的代码,就像您在应用程序中使用

activity.runOnUiThread(new Runnable() {
    public void run() {
        activity.updateDetails(workOrder);
    }
}
这样,您的测试就可以运行了

您收到的非法状态异常似乎是由于您与规则的交互。美国

请注意,当存在此注释时,可能不会使用检测方法


如果您在
之前在
@中启动/获取活动,它也应该可以工作。

您可以在以下帮助下在主UI线程上运行部分测试:

在大多数情况下,使用
UiThreadTest
注释测试方法更简单,但是,它可能会导致其他错误,例如
java.lang.IllegalStateException:无法在主应用程序线程(on:main)
上调用方法

FYR,这里引用的是的Javadoc:

注意,由于当前JUnit的限制,在UI线程上也会执行在
之前和之后加上
注释的方法如果这是一个问题,请考虑使用rununuithread(Runnable)。


请注意上面提到的
UiThreadTest
(package
android.support.test.annotation
)不同于((package
android.test
)。

公认的答案完美地描述了正在发生的事情

另外,如果有人想知道为什么Espresso的触动用户界面的方法,例如
perform(ViewActions…
)不需要这样做,那只是因为他们后来为我们做了

如果您遵循
perform(ViewActions…
,您会发现它最终会执行以下操作(在
android.support.test.espresso.ViewInteraction
):

mainThreadExecutor
本身用
@MainThread
注释


换句话说,意式浓缩咖啡也需要遵循David在公认答案中描述的相同规则。

公认答案现在已被弃用

实现这一点的最简单方法是使用
UiThreadTest

import android.support.test.annotation.UiThreadTest;

        @Test
        @UiThreadTest
        public void myTest() {
            // Set up conditions for test

            // Call the tested method
            activity.doSomethingWithAView()

            // Verify that the results are correct
        }

在androidx测试运行程序中,添加了一个新类
UiThreadStatement
,该类提供了一个
runOnUiThread
方法

        UiThreadStatement.runOnUiThread {
           // call activity here 
        }

当与
getInstrumentation().waitForIdleSync()结合使用时,
runOnUiThread
方法起作用。不幸的是,之前的
@方法没有起作用。谢谢你的帮助当您在之后立即有一个断言时,这一点很重要,否则您可能会得到一个测试结果不一致的竞争条件!如果未来的访问者偶然发现
Android.Test.UIThreadTest在API 24:Android 7.0(Nougat)
之后被弃用,请注意这不是相同的注释。此答案使用支持注释。虽然为我做过牛轧糖
myTest
这项活动,但我无法解决这个问题?这就是我一直坚持的。
import android.support.test.annotation.UiThreadTest;

        @Test
        @UiThreadTest
        public void myTest() {
            // Set up conditions for test

            // Call the tested method
            activity.doSomethingWithAView()

            // Verify that the results are correct
        }
        UiThreadStatement.runOnUiThread {
           // call activity here 
        }