Первое действие не останавливается при запуске второго действия

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

У меня есть два занятия HomeActivity и DetailActivity.

Шаг 1. Нажав кнопку на HomeActivity, вы перейдете к DetailActivity

Шаг 2. Назад нажмите на DetailActivity, чтобы перейти к HomeActivity

При переходе к DetailActivity следует вызывать onStop из HomeActivity в соответствии с жизненным циклом активности, поскольку DetailActivity получает onStart. Но onStop не вызывается, если я быстро нажимаю DetailActivity.

Жизненный цикл активности при немедленном нажатии назад.

HomeActivity: onPause
DetailActivity: onStart
DetailActivity: onResume
DetailActivity: onPostResume
DetailActivity: onPause
HomeActivity: onResume
HomeActivity: onPostResume
DetailActivity: onStop

Жизненный цикл активности, если вернуться назад после задержки (скажем, через несколько секунд в DetailActivity)

HomeActivity: onPause
DetailActivity: onStart
DetailActivity: onResume
DetailActivity: onPostResume
HomeActivity: onStop
DetailActivity: onPause
HomeActivity: onStart
HomeActivity: onResume
HomeActivity: onPostResume
DetailActivity: onStop

Разве это не похоже на ошибку, когда запускается новый Activity, предыдущее действие не останавливается?


person Libin    schedule 28.07.2016    source источник
comment
Если вы не закончите первое действие, оно останется в фоновом режиме, будет запущен только метод onPause. Это нормальное поведение, используйте finish() сразу после startActivity(...)   -  person Chol    schedule 28.07.2016
comment
@Chol- Нет, это не так. HomeActivity получает onStop, если обратное нажатие не быстро на DetailActivity. Проблема только в том случае, если вы нажмете назад сразу   -  person Libin    schedule 28.07.2016
comment
если предыдущая активность не является полностью невидимой.   -  person sanemars    schedule 28.07.2016
comment
Посмотрите на этот ответ stackoverflow.com /вопросы/5625428/   -  person Chol    schedule 28.07.2016
comment
Прочитайте это: developer.android.com/training/basics/activity-lifecycle /   -  person Mark Keen    schedule 28.07.2016
comment
@Chol - я читал эти ответы, onStop() в некоторых ситуациях не будет вызываться. Что за ситуация, которую я пытаюсь понять?   -  person Libin    schedule 28.07.2016
comment
Не знаю, я думаю, что это сам андроид обрабатывает, не уверен, что мы можем что-то сделать.   -  person Chol    schedule 28.07.2016
comment
в некоторых ситуациях, например, при быстром возвращении к деятельности. Вы обнаружили один!   -  person 323go    schedule 28.07.2016
comment
Согласно документации, onStop() вызывается, когда активность больше не видна и полностью скрыта от пользователя. Похоже, что немедленный переход назад из другого действия — отличный способ гарантировать, что условия, вызывающие срабатывание onStop(), никогда не наступят. Почему ты удивлен?   -  person iheanyi    schedule 28.07.2016
comment
@ 323go, который применим только к предварительным сотам onStop. ОП не указал, какая версия используется. В любом случае то, что здесь описано, является нормальным поведением onStop, но до и после соты. Здесь нет какой-либо ситуации (недостаточно памяти, телефон вот-вот выключится).   -  person iheanyi    schedule 28.07.2016
comment
@iheanyi - Давление назад - не единственный сценарий, по которому это происходит. Это также происходит, если вы нажимаете кнопку на DetailActivity и переходите к HomeActivity. Разве это не означает, что если я могу взаимодействовать со вторым действием (нажав кнопку), действие полностью запущено, а первое должно остановиться?   -  person Libin    schedule 28.07.2016
comment
@Libin onStop() вызывается, когда действие больше не видимо, а не когда выполняется другое действие.   -  person iheanyi    schedule 28.07.2016
comment
@iheanyi . Да, но здесь видно новое действие, не означает ли это, что предыдущее действие невидимо?   -  person Libin    schedule 28.07.2016
comment
@Libin Нет. То, что новое действие видно, не означает, что предыдущее невидимо. Простейшим примером этого является то, что предыдущее действие занимает весь экран, а новое использует только маленькое окно посередине.   -  person iheanyi    schedule 28.07.2016
comment
Я также обновил свой ответ, чтобы указать на случай, когда это могло произойти, даже если старая активность полностью скрыта.   -  person iheanyi    schedule 28.07.2016


Ответы (2)


Согласно документам Android об остановке и перезапуске действия

Пользователь выполняет действие в вашем приложении, которое запускает новую активность. Текущее действие останавливается при создании второго действия. Если затем пользователь нажимает кнопку «Назад», первое действие перезапускается.

Они должны обновить его, чтобы сказать If the user the presses the Back button but not to quickly ха-ха, но я думаю, что iheanyi прав в том, что какой-то другой процесс мог быть предоставлен время процессора после того, как DetailsActivity нажала onPostResume и была нажата кнопка «Назад», прежде чем ОС смогла продолжить процесс onStop HomeAcitvity

person Zabador    schedule 28.07.2016

Вы описали нормальное поведение. Вот что https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle говорит об этом:

Вызывается, когда действие больше не видно пользователю, потому что другое действие было возобновлено и покрывает это. Это может произойти либо из-за того, что начинается новая деятельность, либо из-за того, что существующая ставится перед этой, либо из-за того, что эта деятельность уничтожается. За ним следует либо onRestart(), если эта активность возвращается для взаимодействия с пользователем, либо onDestroy(), если эта активность уходит.

Итак, вам может быть интересно, хорошо, если моя новая активность видна, не означает ли это, что предыдущая активность невидима? Не совсем. Ваша новая активность может не полностью перекрывать старую (в этом случае часть старой все еще видна). Это может быть особенно сложно, если в старой активности есть элементы, которые хотя и «невидимы» для пользователя, поскольку выглядят так же, как элементы из новой активности, но технически все еще видимы (в том смысле, что они не полностью заблокированы новой).

Помимо видимости, у вас также могут быть непреднамеренные проблемы с синхронизацией методов жизненного цикла, которые приводят к этому. Допустим, ваш onPause() занимает много времени. Другая активность может полностью скрыть старую, удовлетворяя условиям для onStop(), но вы вернетесь назад до того, как onStop() сможет запуститься.

Наконец, есть много задач, которые нужно выполнять на телефоне, и мало процессоров для их выполнения. Обязательно некоторые задачи будут иметь более высокий приоритет, чем другие. Подумайте о коде, который должен выполняться, когда ваша новая активность выходит на передний план — у onStop() нет времени для запуска, если телефон занят выполнением кода для вашей активности. Если этот код затем вызывает onResume, onStop будет вообще пропущен.

Как видно из диаграммы жизненного цикла, вы можете перейти от onPause() обратно к onResume(), минуя onStop(). Возможно, вам следует подумать о сценариях, в которых что-то подобное может произойти (и почему), чтобы лучше понять ваш конкретный случай.

person iheanyi    schedule 28.07.2016
comment
Оба моих действия представляют собой полноэкранный макет, поэтому проблема не в том, что они могут не полностью перекрывать старый. Я ничего не выполняю на onPause, кроме журнала. Похоже, что если активность переходит в onStart, она должна оставаться активной в течение нескольких секунд, прежде чем переходить в onPause, иначе предыдущая активность не получит onStop. Это кажется мне ошибкой, поэтому я не понимаю - person Libin; 28.07.2016
comment
Я не уверен, почему вы думаете, что это ошибка. Похоже, у вас простое (и неправильное) представление о том, как работает ОС. По сути, ваши два действия — не единственные, что выполняется на данном телефоне, и они не обязательно имеют одинаковый приоритет (или вероятность получения времени выполнения). Есть много вещей, которые нужно запустить, и гораздо меньшее количество процессоров для их запуска. Неизбежно, некоторые задачи получат более высокий приоритет, чем другие. Таким образом, вы не должны ожидать, что onStop() будет вызываться в тот момент, когда активность становится скрытой. То, что вы видите, это то, чего вы должны ожидать. - person iheanyi; 28.07.2016
comment
@libin взгляните на диаграмму жизненного цикла. Как видите, вы можете перейти от onPause() обратно к onResume(), минуя onStop(). Кажется, вы думаете, что вы гарантированно нажмете onStop() после onPause(). - person iheanyi; 28.07.2016
comment
Я не ожидаю, что onStop всегда будет вызываться после onPause. Я думаю, что когда действие получает onResume (видимое для взаимодействия с пользователем), предыдущее действие должно получить onStop, вот в чем проблема. - person Libin; 29.07.2016
comment
@Libin Я могу понять, почему у вас могут быть такие ожидания, но это поведение не указано в документации. - person iheanyi; 29.07.2016