等待回调而不阻塞主线程

Wait for callback without blocking main thread

我被困住了,很乐意得到任何帮助!

我正在为 android 库编写测试。任务是在 activity 中执行一些操作并检查库是否正确响应。 我的问题是我的测试在 activity 中的所有操作完成后立即完成,但我通过回调获得测试结果(并且我仅在测试结束时收到此回调)。所以,我想以某种方式告诉测试框架,直到收到回调(或直到时间用完),测试才结束。这是我现在拥有的:

@Test
public void testSimpleSetup() {

    /* ... */

    InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
            testManager.startTest(MAX_WAIT_TIME); // this object calls onTestResult(boolean) after time t (t <= MAX_WAIT_TIME)

            /* working with activity here */
        }
    });
    InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}

@Override
public void onTestResult(boolean passed) {
    // assertTrue(passed);
    Assert.fail();
}

我预计此测试会失败,但实际上 onTestResult 是在 testSimpleSetup 完成后调用的,断言对测试结果没有影响。

提前致谢。

检查this post. I modified a bit the code, since I read the following

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

Object mon = new Object(); //reference in your Activity
boolean testOnGoing = true;
/*...*/

InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
           synchronized (mon) {
           testManager.startTest(MAX_WAIT_TIME); 
           /* working with activity here */
           while(testOnGoing)
              mon.wait();
           } 
        }
});

InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}

@Override
public void onTestResult(boolean passed) {
synchronized (mon) {    
    //assertTrue(passed);
    Assert.fail();
    testOnGoing = false;
    mon.notify();
   } 
}

感谢@Gordak。他的回答几乎奏效了。但是,不幸的是,它阻塞了主线程,所以测试永远不会结束。我稍微修改了一下,现在可以用了。

@Before
public void setUp() throws Exception {
    activity = testRule.getActivity();
    latch = new CountDownLatch(1);
}

@Test
public void testSimpleSetup() {

    /* ... */

    InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
            testManager.startTest(MAX_WAIT_TIME); // this object calls onTestResult(boolean) after time t (t <= MAX_WAIT_TIME)

            /* working with activity here */
        }
    });
    InstrumentationRegistry.getInstrumentation().waitForIdleSync();

    latch.await(); // here we block test thread and not UI-thread
                   // presumably, you will want to set the timeout here
}

@Override
public void onTestResult(boolean passed) {
    // assertTrue(passed);
    Assert.fail();
    latch.countDown();
}