ActivityUnitTestCase и Activity#runOnUiThread

Мой тест фокусируется на завершении AsyncTask и проверке того, что последующая Activity запущена.

Известно, что AsyncTask#onPostExecute не вызывается, если экземпляр AsyncTask не создается и не выполняется из потока пользовательского интерфейса, поэтому мой (видимый в тесте) метод для вызова AsyncTask проходит необходимые меры предосторожности для обеспечения такого поведения — через Runnable, который немедленно запускается, если в потоке пользовательского интерфейса или запланировано для запуска в потоке пользовательского интерфейса.

Когда этот метод вызывается из теста ActivityUnitTestCase, Runnable, который создает экземпляр и выполняет эту AsyncTask через Activity#runOnUiThread, в конечном итоге работает в потоке, отличном от потока пользовательского интерфейса. Есть ли способ гарантировать, что этот Runnable будет выполняться в потоке пользовательского интерфейса из действия?

Добавления:

  • Тест выполняется, как и предполагалось, в соответствии с ActivityInstrumentationTestCase2. класс, но у меня нет доступа к ActivityUnitTestCase#getStartedActivityIntent. я в курсе Instrumentation.ActivityMonitor, и это не решение.
  • Runnables, запланированные на ActivityUnitTestCase#runTestOnUiThread doзапускаются в пользовательском интерфейсе нить.
  • Я не собираюсь переопределять свой тест.
  • Как ни странно, ActivityUnitTestCase#startActivity вызывает Activity#onCreate НЕ в потоке пользовательского интерфейса.

Редактировать: Вот фрагмент (непроверенного) кода, который демонстрирует суть проблемы:

// ExampleActivityTests.java

class ExampleActivityTests : public ActivityUnitTestCase <ExampleActivity> {

    public void testThatRequiresUiThread() {

        startActivity (new Intent(), null, null);
        // ...call instrumentation onStart, onResume...

        runTestOnUiThread(new Runnable() {
            public void run() {
                boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
                Log.d ("A", "Running on UI Thread? " + isUiThread);
            }
        });

        getActivity().methodRequiringUiThread();

        // assertions here...
    }
}

// ExampleActivity.java -- just the relevant method

    public void methodRequiringUiThread() {

        runOnUiThread(new Runnable() {
            public void run() {
                boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
                Log.d ("B", "Running on UI Thread? " + isUiThread);
            }
         });
    }

В LogCat мы увидим:

A | Running on UI Thread? true
B | Running on UI Thread? false
6
задан Travis 14 March 2012 в 03:42
поделиться