Обработчик не выполняет Runnable в инструментальном тесте

Я написал инструментальный тест Android, который вызывает мою службу и получает ответ через широковещательную рассылку.

Тестируемый код, который обращается к службе, использует обработчик.

В процессе тестирования моего теста ^^ я заметил, что обработчики ведут себя не так, как ожидалось. Итак, я написал тест, чтобы проверить это поведение:

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

Обработчик не выполняет исполняемый код. Это также проблема с моим производственным кодом.

У меня возникла проблема с Looper.prepare(), которую я исправил с помощью аннотации @UiThreadTest.

Есть ли какие-либо предложения относительно моей проблемы с обработчиком?


person addyi    schedule 25.07.2018    source источник
comment
stackoverflow.com/a/44651415/549372   -  person Martin Zeitler    schedule 25.07.2018
comment
@MartinZeitler Спасибо, но на самом деле это не решение моей проблемы.   -  person addyi    schedule 25.07.2018


Ответы (1)


Причина в том, что вы заблокировали свой thread здесь:

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

И когда thread заблокирован, вы не можете отправить rannable со своим handler. Thread просто заблокирован. Вы можете решить эту проблему, связав свой handler с другим thread. Вот простое решение через 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();
    }
}
person yshahak    schedule 26.12.2018