подробности уничтожения и восстановления компонентов приложения Android - PullRequest
20 голосов
/ 08 ноября 2011

Может ли кто-нибудь подтолкнуть меня в направлении какой-то конкретной, заслуживающей доверия (и желательно краткой) информации о следующем:

  1. Порядок, в котором компоненты уничтожаются и (где применимо) восстанавливаютсясистемой (Фрагмент, Активность, Потоки / AsyncTasks / Таймеры действия, статические данные (когда классы выгружаются?), Потоки / AsyncTasks / Таймеры в других классах, хост TabActivity, ActivityGroup, связанные локальные сервисы, Приложение, процесс), когдаприложение находится в фоновом режиме и на переднем плане.
    В какой момент уничтожение может прекратиться (с какими состояниями можно столкнуться при возврате в приложение - например, «все, включая объект приложения уничтожен, процесс жив»)1007 *

  2. Возможно ли (без модификации Android) программно вызвать такое же разрушение самостоятельно, чтобы оно было неотличимо от того, когда система это делает, или это отдельный механизм, необходимый для того, когда мы сами решаемсвободная память (запускается onLowMemory)?

  3. Надежные шаги воспроизведения всех сценариев из 1) (будет ли работать junit.framework?Я не исследовал это)?

  4. " Если пользователь покидает задачу на долгое время, система очищает задачу от всех действий, кроме корневого действия. Когдапользователь снова возвращается к задаче, восстанавливается только действие root": это помимо жизненного цикла / уничтожения процесса / компонента или связано с ним?

Я прочиталразличные источники дают фрагменты информации, часто неполные и вводящие в заблуждение, иногда неверные.
Признаюсь, я пролистал некоторые части документации, поэтому я мог что-то упустить или неправильно понять.

[ПРАВИТЬ] ВВо избежание недоразумений: я спрашиваю, что Android уничтожает компоненты для освобождения памяти, в обход Activity.onDestroy.
Когда я помещаю приложение в фоновый режим и возвращаюсь позже, произойдет одна из следующих последовательностей:

  • onPause, onStop, onRestart, onStart, onResume
  • onPause, onStop, Application.onCreate, onCreate (notNull), onStart, onResume

[EDIT2] Баунти начался.Нужна надежная информация о: действиях, фрагментах, приложениях, связанных (потенциально удаленных) сервисах, процессах.
Сценарии частичного / полного уничтожения.Смотри 1-ю точку.

Ответы [ 6 ]

2 голосов
/ 14 февраля 2013

Кредит за это идет на hackbod для записи здесь (прочитайте весь ответ) и на CommonsWare для ссылки в комментарии.

Короче говоря: все документы , переписанные много раз, продолжают нам лгать. Они не вводят в заблуждение, они просто дают нам неверную информацию. Если вы не используете фрагменты (не знаю, если поддержка v4 тоже имеет значение), Android освобождает память, убивая весь процесс, или ничего не делает.

Конечно, это не относится ко всему:

  • Пункт 4 вопроса
  • Почему я часто видел onCreate (notNull) при нажатии Back в стеке Activity, когда Activity обрабатывает все изменения конфигурации (Android 2.3.7)
  • Как это связано с широко распространенным убеждением, что onPause - это последний вызов, который вы обязательно получите, и onStop, возможно, никогда не вызовут (как тогда приложение может перейти в фоновый режим и быть убитым?)

Мы куда-то добираемся.

1 голос
/ 01 декабря 2011

Это то, что мой опыт и опыт разработчиков я, кажется, предлагает:

    • Фрагменты не уничтожаются автоматически.
    • невидимые Действия в стеке приложения могут быть автоматически уничтожены в любом порядке и в любом количестве.
    • уничтоженные Потоки Действия (или любого другого класса) и статика остаются нетронутыми, пока Приложение не будет уничтожено.
    • TimerTasks: не проверял.
    • связанные локальные Услуги: уничтожено где-то между уничтожением последней Связывающей Деятельности и Приложения.
    • Приложение - это последнее, что входит в процесс и «идет» вместе со всеми потоками.
    • процесс может существовать в течение длительного (20+ минут) времени после уничтоженияОбъект приложения, если только у вас нет автоматического убийцы задач.
    • Действия в TabActivity или в ActivityGroups не уничтожаются автоматически, а выполняются сразу, если контейнер уничтожен.
      Пример:TabActivity с ActivityGroups под вкладками.Все мероприятия в прямом эфире.Другая активность запущена, полноэкранная.TabActivity со всем, что в нем есть, теперь может быть уничтожено Android, сразу или совсем не так.
  1. NO .
    Если вы уничтожите активностьвручную он проходит весь жизненный цикл и не передает Bundle в onCreate при повторном запуске.
    Кроме того, onLowmemory ненадежен - даже при небольших шагах выделения он никогда не может быть вызван до того, как будет выдан OutOfMemoryError.
  2. NO .
    Несмотря на то, что автоматическое удаление / восстановление является такой важной функцией в Android, нет никакого способа проверить такие сценарии.
  3. Это, вероятно, связано только в зависимости от того, существует ли этот процесс или нет.Если это произойдет, Android попытается восстановить старые действия.Если нет, то это чистый перезапуск.

Выше приведены некоторые предположения.
Я все еще жду, когда кто-нибудь подтвердит это и предоставит несколько документов (гарантии не зависят от текущей реализации классов).
Пожалуйста, ПОЖАЛУЙСТА, исправьте меня, если что-то из этого не так.

Редактировать: Приведенная выше информация может быть устаревшей, она была протестирована на Android 2.1-2.3

0 голосов
/ 09 октября 2013

Когда дело касается действий, они будут уничтожены только в Destroy () до тех пор, пока разработчик вручную не вызовет функцию finish (),

Жизненный цикл фрагмента полностью соответствует его родительскому действию, поэтому, когда родительское действие разрушается на Destroy (), также будут вызываться фрагменты на Destroy ().

Задачи таймера завершат свою работу и станут кандидатами на сборку мусора. После того, как действие создаст их, задача выполняется в своем собственном потоке, без связи с действием, даже если действие уничтожено, задача завершается сама ....

0 голосов
/ 29 августа 2013
  1. Метод ActivityManagerService # trimApplications () удаляет все неиспользуемые процессы приложения, если текущий получатель приложения имеет нулевое значение, не имеет активности и службы.
0 голосов
/ 14 июня 2013

Что ж, мой друг, я думаю, у тебя будут большие проблемы в твоих исследованиях.В основном потому, что вы говорите о двух черных ящиках: сборщике мусора Dalvik и диспетчере кучи Android.Я бы сказал, что вы не можете доверять тому, что андроид будет следовать любому порядку уничтожения объектов.Но вы можете быть уверены, что этот жизненный цикл будет соблюдаться [Программирование Android, 2011]:

Жизненный цикл активности:

onCreate() - Called after the instance of the activity has been created for the first  time
onRestart() - Called after an activity has been interrupted, just before the onStart();
onStart() - Called when the object activity and their visions become visible to the user;
onResume()-  Called when the object activity and their visions become interactive to the user;
onPause() - Called when a different instance of the activity is going to get visible and the present activity ceases to interact with the user
onStop() - Called when the activity is no longer visible or is not interacting
onDestroy() - Called when an activity instance must be destroyed and it's no longer needed. 

Фрагменты имеют разные жизненные циклы, включая методы onAttach, onCreateView и onActivityCreated.Но почему вас волнует порядок уничтожения объектов?Я не вижу причин для вас следить за такими событиями, но если вам действительно нужно, узнайте больше о сборщике мусора.

0 голосов
/ 12 ноября 2011

Это не полный ответ, но я бы порекомендовал вам размещать тостовые сообщения в каждом из этих методов.Добавьте свои собственные onPause(), onStop(), onResume() и т. Д. И внутри поместите строку, подобную этой:

Toast.makeText(this, "onPause()", Toast.LENGTH_SHORT).show();

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

Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);

, вместо этого появится вызов onNewIntent(), если оно уже было создано.Подводя итог, лучше всего просто смотреть сообщения Тоста.Также вам действительно нужно сосредоточиться на использовании отладчика.Поместите точку останова на каждый метод, и вы сможете увидеть его.В одном я уверен, что вы не можете напрямую вызывать такие методы, как onPause().Также имейте в виду, что в общем случае вы не знаете, когда будет вызван onDestroy().

...