简体   繁体   中英

Handler not executing Runnable in Instrumentation Test

I have written an Android instrumentation test that calls my service and receives an answer via an broadcast.

The code to be tested, which speaks to the service, uses handler.

In process of testing my test ^^ I noticed that the handlers are not behaving as expected. So I've written an test to check on this behaviour:

import android.os.Handler;
import android.support.test.annotation.UiThreadTest;

import org.junit.Assert;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@RunWith(AndroidJUnit4.class)
public class HandlerTest {

    private CountDownLatch countDownLatch;

    @Test
    @UiThreadTest
    public void handlerTest() {

        final Handler handler = new Handler();
        countDownLatch = new CountDownLatch(1);

        final Runnable r = new Runnable() {
            @Override
            public void run() {
                // this code gets not executed
                countDownLatch.countDown();
            }
        };

        handler.postDelayed(r, 1000);

        try {
            final boolean finishedWithoutTimeout
                    = countDownLatch.await(5, TimeUnit.SECONDS);
            Assert.assertTrue(finishedWithoutTimeout);

        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }
}

The handler dosn't execute the runnable code. This is also the problem with my production code.

I got a problem with Looper.prepare() that I fixed with the @UiThreadTest annotation.

Are there any suggestions regarding my handler problem?

The reason is that you locked your thread here:

final boolean finishedWithoutTimeout = countDownLatch.await(5, TimeUnit.SECONDS);

And when the thread is locked, you can't send a rannable with your handler . The Thread is just locked. You can solve it by linking your handler to another thread . Here is a simple solution via handlerThread :

@Test
@UiThreadTest
public void handlerTest() {
    countDownLatch = new CountDownLatch(1);
    final HandlerThread handlerThread = new HandlerThread("solution!");
    handlerThread.start();
    final Runnable r = new Runnable() {
        @Override
        public void run() {
            countDownLatch.countDown();
        }
    };
    Handler handler = new Handler(handlerThread.getLooper());
    handler.postDelayed(r, 1000);
    try {
        final boolean finishedWithoutTimeout = countDownLatch.await(5, TimeUnit.SECONDS);
        Assert.assertTrue(finishedWithoutTimeout);
    } catch (final InterruptedException e) {
        e.printStackTrace();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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