Как остановить и перезапустить активность в тесте на андроид?

Я пытаюсь написать тест инструментальной активности Android, который останавливается (onPause(), затем onStop()) и перезапускает текущую активность. Я попробовал

activity.finish();
activity = getActivity();

... но это не работает должным образом.

Цель теста - утверждать, что данные формы сохраняются во время метода onPause() и перечитываются во время метода onStart(). Он работает при выполнении этого вручную, но тест не выполняется, из которого я делаю вывод, что activity.finish() представляется неправильным способом остановить и перезапустить активность.


Изменить: Моя основная проблема, похоже, связана с синхронизацией. После перезапуска действия тестовый бегун не дождался завершения всех обработчиков событий. Следующая строка останавливает выполнение теста до тех пор, пока активность не будет работать:

getInstrumentation().waitForIdleSync()

Кроме того, взгляните на принятый ответ на более ценную информацию о жизненном цикле.

Ответы

Ответ 1

Вызывая (или инициируя изменение ориентации экрана):

activity.finish(); // old activity instance is destroyed and shut down.
activity = getActivity(); // new activity instance is launched and created.

Вызывает активность в течение всего жизненного цикла отдыха:

onPause() -> onStop() -> onDestroy() -> onCreate()

Что вам нужно:

onPause() -> onStop() -> onRestart()

Недавно я разоблачил Instrumentation API и нашел много интересного метода триггера жизненного цикла активности callActivityOnXXX(), следующая одиночная строка кода должна делать сложный:

MyActivity myActivity = getActivity();
// make activity falling into restart phase:
getInstrumentation().callActivityOnRestart(myActivity);

Диаграмма жизненного цикла активности, приведенная в официальном руководстве для разработчиков: enter image description here

Ответ 2

Я пробовал вызывать .finish(), setActivity (null), getActivity() и перезапускает действие, но для меня это не восстанавливало состояние. Я опробовал все остальные ответы на SO, и каждый другой способ сделать это я мог найти в Интернете, и никто из них не работал у меня. После долгих экспериментов я нашел следующие работы (nb: требуется уровень API 11 +):

    getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
            activity.recreate();
        }
    });
    setActivity(null);
    activity = getActivity();

Когда я делаю это, создается новый экземпляр Activity, а также создается новый экземпляр фрагмента, который я связал с активностью ранее в тесте, и как активность, так и фрагмент восстанавливают свое состояние ожидаемым образом.

Я не знаю, как это работает или почему это работает, я достиг этого решения с помощью проб и ошибок, и я тестировал его только на Nexus 4, работающем с KitKat. Я не могу гарантировать, что он правильно имитирует активный отдых, но он работал для моих целей.

Edit: На более позднем этапе я понял, как это работает. getActivity() работает через регистрацию перехватчиков, которые получают новые Создаваемые действия, которые захватывают новую активность, созданную activity.recreate(). setActivity(null) требовалось очистить внутреннюю поддержку кеша getActivity, иначе он вернет старый и не будет искать новый.

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

Ответ 3

Хороший способ проверить события жизненного цикла - это изменения ориентации экрана. По моему опыту это удобный способ бомбардировки шаблона onPause/onStart.

Ответ 4

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