Как остановить и перезапустить активность в тесте на андроид?
Я пытаюсь написать тест инструментальной активности 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
Возможно, вы могли бы попытаться сохранить имя своей деятельности,
закончить его... и использовать отражение, чтобы получить новый экземпляр класса. для нового намерения создать...
Ответ 5
Измените свой код следующим образом:
mActivity.finish();
setActivity(null);
mActivity = this.getActivity();
Полное объяснение можно найти в этом вопросе