Что на самом деле происходит, когда вы удаляете приложение из списка последних приложений?

В список недавних приложений в Ice Cream Sandwich добавлена ​​возможность удалять приложения из списка, тем самым удаляя их навсегда (и, насколько я знаю, это ванильная функция, а не функция CM/custom ROM). Документация и сведения о платформе, похоже, не охватывают внутреннюю работу этой функции, но мне любопытно узнать, что на самом деле делает система.

Еще больше усилив мое любопытство, я решил провести быстрый тест: я запустил Music при установке CM9, а затем отказался от него. Затем я проверил список последних приложений и увидел, что оно действительно там (и в правильном состоянии, судя по миниатюре). Затем я вошел Settings->Applicationsи принудительно остановил приложение «Музыка», но оно все еще было в списке недавних, что заставило меня поверить, что оно не связано с процессами, продолжающимися в фоновом режиме.

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

Итак, что на самом деле происходит на уровне ОС, когда вы удаляете приложение из списка недавних? Он просто удаляет данные приложения из ОЗУ и собирает их, уничтожая сохраненное состояние?

Ответы (5)

Удаление приложений из списка недавних приложений — это ваниль, и да, оно плохо документировано. Это было темой приличного количества дискуссий на различных форумах Android ... консенсус, кажется, лучше всего описан здесь в некоторых комментариях : поведение похоже, но не совсем то же самое, что и закрытие приложения - в целом ( для приложений, которые не определяют явную обработку кнопки «Назад»), это то же самое, что достаточное количество раз вернуться из приложения, которое вы выходите из него.

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

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

Спасибо, по этой ссылке много хороших обсуждений. Вы также можете быть правы относительно музыки, возможно, это был плохой тест. Я попробую другое приложение, просто для удовольствия.
Собираюсь пойти дальше и принять это, поскольку обсуждение на Reddit помогло мне найти лучшие условия поиска и, похоже, подтверждается некоторыми сообщениями Дайанны Хакборн, которые я отметил в своем ответе . Спасибо!
Отлично спасибо! Мне помог этот пост: reddit.com/r/Android/comments/mpevh/…
Сторонние музыкальные проигрыватели, такие как Rocket Player, останавливают музыку, когда вы пролистываете приложение из списка «Последние», даже если служба работает в фоновом режиме, и вам нужно снова открыть приложение или воспроизвести в виджете, чтобы включить музыку.

Кажется, я нашел волшебные условия поиска, которые привели к некоторым объяснениям от сотрудников Google. В частности, я нашел несколько разных мест, где Дайан Хэкборн объясняет, что происходит, когда вы смахиваете что-то из списка последних. Первый — это комментарий к одному из ее постов в Google+ :

[Что] конкретно происходит, когда вы смахиваете недавнюю задачу: (1) убивает все фоновые или пустые процессы приложения (см. http://developer.android.com/guide/topics/fundamentals/processes-and- threads.html#Lifecycle для того, что это означает) и (2) использует новый http://developer.android.com/reference/android/app/Service.html#onTaskRemoved(android.content.Intent) API, чтобы сообщать о любых службы приложения об удалении задачи, чтобы оно могло делать все, что считает нужным.

Она также отмечает в комментарии в блоге :

На самом деле, удаление записи в недавних задачах уничтожит все фоновые процессы, существующие для этого процесса. Это не приведет к остановке служб напрямую, однако для них есть API, чтобы узнать, что задача была удалена, чтобы решить, хотят ли они, чтобы это означало, что они должны остановиться. Это сделано для того, чтобы удаление, скажем, недавней задачи приложения электронной почты не приводило к прекращению проверки электронной почты.

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

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

Это, конечно, неочевидное поведение, очень интересно!
«убить все фоновые процессы, существующие для процесса. Это не приведет к остановке служб напрямую». Это все еще правда? Вчера я провел тест. Вчера я удалил приложение с фоновой службой в основном процессе. Приложения => работающий пользовательский интерфейс показал 0 процессов и 0 служб. Позже я удалил то же приложение с процессом, работающим в отдельном конкретном приложении. Приложения => работающий пользовательский интерфейс сказал, что у меня 0 процессов и 1 служба. Это было на Moto X (2014) с Android 4.4.4.
@StevenWexler: Возможно, в первом случае служба завершилась сама по себе, но не во втором, или во втором сценарии основной процесс определил (по какой-то причине), что он не хочет останавливать службу. Трудно знать наверняка.
запущенная служба запускается снова автоматически после удаления из недавнего списка, ее onCreate снова вызывается. но в некоторых приложениях onCreate вызывается до onTaskRemoved, а в некоторых вызывается после onTaskRemoved. почему тогда такое поведение?

В исходном коде есть некоторая информация в классах com.android.internal.policy.impl.RecentApplicationsBackground и com.android.internal.policy.impl.RecentApplicationsDialog .

Если я правильно их прочитал, есть специальные обработчики для выбора приложений, но ничего особенного для их прокрутки, кроме onDetachedFromWindow(), который вызывает, com.android.View.onDetachedFromWindow()который в основном скрывает элемент и очищает его данные. Это намекает на тот факт, что при пролистывании приложения ничего особенного не происходит, что соответствует ответу Остина Миллса, потому что, поскольку в списке не отображается активное приложение, onPause()и другие системные вызовы, которые выполняются при «закрытии» приложения уже случилось.

Я думаю, что это будет делать то же самое, что и кнопка «Назад». Кроме одного небольшого изменения. Это будет finish()вся активность/фрагменты в приложении.

Только что провел небольшое тестирование с небольшим приложением для самостоятельной сборки. Вы тоже можете протестировать. Вот мое приложение для тестирования: https://bitbucket.org/Leandros99/lifecycletest (также доступно для скачивания. Для тех, кто не может строить.)
В каждом методе жизненного цикла Activity ( http://developer.android.com/reference/android/app /Activity.html#ActivityLifecycle ) распечатать журнал приложения. Вы можете просмотреть его с помощью adb logcat (установите Android SDK, перейдите к инструментам платформы в cmd / shell и введите adb logcat. Теперь вы увидите, что каждый раз, когда вы делаете что-то вроде нажатия кнопки «Назад» или «Домой», приложение печатает метод жизненного цикла, упомянутый выше. )

Ваш вопрос: если я вытащу приложение из панели недавних приложений, onDestroyбудет вызван метод. Она работает почти так же, как кнопка «Назад».
Надеюсь, я немного помог. Если есть вопросы, просто спрашивайте.

Он закрывает приложение и его данные, хранящиеся в оперативной памяти. Таким образом, вы получаете больше оперативной памяти, чтобы вы могли запускать другие приложения. Однако фоновые службы НЕ закрываются автоматически в результате закрытия используемого приложения.

Хотя это написано повседневным языком, на самом деле это довольно точный ответ - он отражает тот факт, что процесс утилизируется, чего не хватает во многих других ответах (тех, которые ошибочно сравнивают его с кнопкой «Назад»). Однако чего здесь не хватает, так это осознания того, что Android в любом случае избавится от процессов, когда это необходимо для получения памяти, поэтому, хотя он и выполняет некоторую очистку памяти, это будет происходить автоматически, если/когда это необходимо.