Что означает "видимость" в жизненном цикле деятельности? методов onPause против то onStop?
Жизненный цикл активности вызывает у меня головную боль.
Документация по адресу http://developer.android.com/reference/android/app/Activity.html настолько двусмысленно описывает понятие видимости, что я не могу понять, когда onStop()
называется vs onPause()
.
Сравните следующие два утверждения из документации:
(взято справа под диаграммой жизненного цикла)
Методы
onStart()
иonStop()
могут быть вызваны несколько раз, как действие становится видимым и скрытым для пользователя.
Vs
(далее в синей таблице с колонками" убиваемые")
onPause()
вызывается, когда система собирается возобновить предыдущее действие.
Что я понял из первой цитаты, так это то, что onStop()
вызывается на действие A
, Когда A
"скрыто". "Скрытый", я думаю, относится к тому, когда другая деятельность B
была возобновлена и полностью покрывает актвность A
.
Но вторая цитата тогда утверждает, что onPause()
вызывается, когда другая деятельность вот-вот начнет возобновляться. Разве это не полностью скроет активность а? Оба случая, по-видимому, подразумевают, что эта деятельность A
становится "скрытой", не так ли? Согласно моей вероятной ошибочной интерпретации, onPause()
и onStop()
вызываются в идентичных ситуациях.
Документация также, по-видимому, отличается от скрытой (onStop()
вызывается) и частичной видимости (onPause()
получает называемый). Но когда активность еще частично видна? Они имеют в виду буквально? Или действие все еще может считаться "частично видимым", когда оно запустило новое действие (действие вызывает startActivityForResult и запускает действие выбора даты), которое покрывает весь экран? Конечно, деятельность не собирается получить onStop вызывается? Он должен был получить результат в любой момент!
A
теряет фокус (устройство переходит в спящий режим, блокировку экрана и т. д.), На первый план выходит другая активность B
(где активность B
может быть или не быть инициирована активностью A
).
Но в какой момент onStop()
вызывается на действие A
?
Имеет ли значение, сколько действий было сложено на вершине действия а в стеке действий? Существуют ли два различных определения понятия "видимость"?
Извините за стену текста, но я действительно разочарованный: S
Таким образом, встает вопрос: в каких именно ситуациях деятельность считается "скрытой" такой, чтоonStop()
вызывается на нее?
Редактировать:
Я вставил всплывающие уведомления в каждый метод onX и обнаружил некоторые дополнительные странности:
- нажатие кнопки Home будетвсегда вызывать onStop(). Но запуск приложения не вызовет
onRestart()
. Вместо этого он вызываетonCreate()
. Мне это кажется странным, но ладно... - Когда действие "USB Mass Storage" запускается поверх основного действия, вызывается
onStop()
. А при выходе из usb-накопителя активность, возвращаясь к основной активности, называетсяonRestart()
, а неonCreate()
.
Когда устройство переходит в спящий режим и пробуждается, активность проходит только через цикл
onPause()
и onResume()
.
В первом пункте я ожидал вызова onRestart()
при повторном запуске активности. Почему он освободил активность и вызвал onCreate()
вместо этого?
И взгляните на точку nr 2:
Согласно документации: когда "другая деятельность приходит перед деятельностью", onPaused()
должен быть вызван. Разве это не то, что произошло, когда появилась активность USB-накопителя? Он не позвонил onPause()
, он прошел через onStop()
- OnRestart()
цикл! Очевидно, что документация не рассматривает тот случай, когда " приходит другая деятельность в преддверии мероприятия". Так что же произошло на самом деле?
2 ответа:
Хорошо, я думаю, что теперь у меня есть это.
1.
Ключом к первому пункту была эта Ссылка:
Http://code.google.com/p/android/issues/detail?id=2373
Это ошибка. В ссылке есть некоторый код, который полностью решил проблему с созданием новых корневых экземпляров активности, вместо того, чтобы просто перезапустить последнюю активную активность (до того, как была нажата кнопка home).
Я помещаю код в верхней части метода onCreate, чуть ниже супер.вызов onCreate:
if (!isTaskRoot()) { final Intent intent = getIntent(); final String intentAction = intent.getAction(); if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) { finish(); return; } }
Обратите внимание, что я добавил оператор return после завершения, чтобы остальная часть метода onCreate не выполнялась в случае обнаружения ошибки.
2.& 3.
Ключом ко второму и третьему пунктам были эти две связи:Http://answers.oreilly.com/topic/2692-android-programming-understanding-the-activity-life-cycle/
Как сделать активность, не покрывая весь экран
Оказывается, что " видимость" действительно буквально! Поэтому, когда в документации говорится ,что" другая активность идет впереди активности", активность за ударившейся активностью все еще частично видна. Это означает, что менеджер Android Activity должен проверить, является ли bumped Activity полноэкранным действием или нет: если это так,
onStop()
вызывается на предыдущем действии. Если нет, тоonPaused()
вызывается вместо предыдущего действия.Это тривиально объясняет, почему диспетчер USB-накопителей вызвал
onStop()
называемый.Это также означает, что когда устройство переходит в спящий режим, менеджер активности считает его не полноэкранным действием, хотя технически основное действие полностью скрыто за ним.
(смотрите вторую ссылку о том, как сделать не полноэкранные действия)
Интересно, что выпадающее окно (с уведомлениями) не вызывает
onPause()
(и не вызываетonStop()
), хотя это имело бы смысл как не полноэкранное действие. Это должно быть что-то вроде исключение, которое я буду расследовать самостоятельно.Это также означает, что цикл
onStop()-onRestart()
, вероятно, более распространен, чем циклonPause()-onResume()
(хотя оба они все еще должны учитываться), поскольку действия, вероятно, чаще всего являются полноэкранными (лично я думал, что документация указывала на обратное: что onPause-onResume было больше commmon, но, возможно, это только я).Кроме того, это должно означать, что когда основное действие начинает новое полноэкранное действие для a результат, основное действие будет сначала остановлено, а затем перезапущено, когда будет выполнено действие извлечения результата.
Таким образом, единственный вопрос сейчас заключается в том, как лучше всего справиться с приостановленной активностью (то есть, она покрывается не полноэкранной активностью), которая освобождается (хотя этот случай был бы редким). Какие могут быть проблемы? Но это выходит за рамки данного вопроса.