简体   繁体   English

等待回调而不会阻塞主线程

[英]Wait for callback without blocking main thread

I am stuck and will be glad to get any help! 我被困住了,很高兴获得任何帮助!

I am writing tests for an android library. 我正在为一个android库编写测试。 The task is to make some actions in an activity and check that library responds correctly. 任务是在活动中执行一些操作,并检查库是否正确响应。 My problem is that my test finishes just after all actions in activity are done but I get the test result via a callback (and I receive this callback only when the test is over). 我的问题是我的测试仅在活动中的所有操作完成后才完成,但是我通过回调获得测试结果(并且只有在测试结束时才收到此回调)。 So, I want to somehow tell testing framework that the test is not over until the callback is received (or until time runs out). 因此,我想以某种方式告诉测试框架,直到收到回调(或时间用完),测试才结束。 Here is what I have now: 这是我现在所拥有的:

@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();
}

I expect this test to fail but in fact onTestResult is called after testSimpleSetup finishes and Assert has no influence on the result of the test. 我希望该测试失败,但实际上在testSimpleSetup完成后调用onTestResult ,并且Assert对测试结果没有影响。

Thanks in advance. 提前致谢。

Check 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();
   } 
}

Thanks to @Gordak. 感谢@Gordak。 His answer has almost worked. 他的回答几乎奏效了。 But, unfortunately, it blocks the main thread so the test never ends. 但是,不幸的是,它阻塞了主线程,因此测试永远不会结束。 I modified it a little bit so now it works. 我对其进行了一点修改,因此现在可以使用了。

@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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM