Жизненный цикл класса приложения Android

Приложение для Android, над которым я работаю, переопределяет класс Application для хранения облегченного состояния (имя пользователя, местоположение GPS и т. Д.) В статических переменных. Большая часть этого состояния устанавливается в OnCreate активности запуска (имя пользователя, полученное из prefs, запускается прослушиватель местоположения). Безопасно ли полагаться на активность запуска для инициализации класса Application? Существуют ли случаи, когда класс Application может быть воссоздан без создания действия Launch?

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

Обратите внимание, что я попытался протестировать такие сценарии, заставив приложение прекратить использование приложений «Настройки» / «Управление». Однако я не могу воссоздать проблему. При следующем запуске создается класс Application, за которым следует запуск activity.onCreate.

Можно ли предположить, что экземпляр класса Application будет существовать в течение всего процесса и что создание класса Application эквивалентно «перезапуску» приложения, т.е. начать с нового стека действий (и первое действие в стеке - это действие запуска)?


person Patrick Cullen    schedule 03.01.2011    source источник
comment
не уверен, что это помогает, но читали ли вы это: developer.android.com/ guide / themes / fundals.html # actlife.   -  person clamp    schedule 03.01.2011
comment
как ты решил свою проблему?   -  person Sharj    schedule 11.06.2011


Ответы (4)


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

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

То есть процесс (к которому привязано приложение) может быть остановлен, но затем перезапущен, а отдельные действия должны иметь достаточно информации, чтобы воссоздать себя из того, что они сохранили до уничтожения, не полагаясь на глобальное состояние, установленное в процесс другими видами деятельности.

Рассмотрите возможность сохранения постоянного общего состояния, которое требует инициализации с помощью Activity в базе данных SharedPreference или SQLite, или передачу его в Activity, которым это необходимо, в качестве дополнения Intent.

person Yoni Samlan    schedule 03.01.2011
comment
Также developer.android.com/reference/ android / app / - person KingCrunch; 03.01.2011
comment
Фу. Есть предложения о том, как протестировать этот сценарий? Как я уже упоминал, когда я вручную убиваю процесс, стек активности не остается неизменным. - person Patrick Cullen; 03.01.2011
comment
Кстати, я понимаю, что команда Android полностью разработала такое поведение и предпочитает, чтобы мы разрабатывали наши приложения так, чтобы скрыть детали запуска / остановки приложения, но все же было бы неплохо иметь некоторую концепцию пользовательского сеанса. В настоящее время трудно отличить приложение, которое было приостановлено на короткое время, и приложение было приостановлено на длительный период. Получение исправления gps может занять много времени, и было бы неплохо, если бы был более простой способ отметить логическое начало / конец взаимодействия с пользователем, чтобы вы могли решить, получать ли новое исправление или запрашивать учетные данные. - person Patrick Cullen; 03.01.2011
comment
Вы можете создать подкласс (-а) Activity, которые сохранят предпочтение для pauseTime () в их onPause () и удалят его onResume (), с onCreate (), которые ищут наличие этой отметки времени и вызывают некоторый метод onNewSession () в вашем приложении, если эта временная метка превышает определенное значение, если вы действительно хотели ... Но система предполагает, что пользователь всегда продолжает сеанс с того места, где он остановился, если только он не ушел на особенно долгое время (в этом случае система будет очистите стек задач - см. developer.android.com/guide/topics/fundamentals .html # clearstack). - person Yoni Samlan; 03.01.2011
comment
Вы можете проверить это, покинув свое приложение (например, перейдя домой), а затем завершив процесс. Если вы завершите процесс, когда приложение находится на переднем плане, система подумает, что в приложении что-то сломано, и произведет некоторую очистку, например, удалит его главное действие, чтобы избежать плохих состояний бесконечного перезапуска, в которые могут попасть приложения. - person hackbod; 03.01.2011
comment
Похоже, у меня это не работает. Я пробовал на двух устройствах (1.6 и 2.3) - я помещаю приложение в фоновый режим с помощью аппаратной кнопки «Домой», затем вручную останавливаю из управления приложениями, щелкаю значок моего приложения на главном экране. Приложение по-прежнему перезапускается с запуском. И дело не только в очистке верхней активности - стек состоит из нескольких действий, когда я помещаю его в фоновый режим. И, конечно же, android: cleartaskonlaunch не установлен ... - person Patrick Cullen; 03.01.2011
comment
Я думаю, что потребность в постоянном состоянии приложения - еще одна причина использовать ContentProvider. - person louielouie; 14.03.2012
comment
Я очень благодарен за эти вопросы и ответы, потому что я обнаружил, что глобальное состояние моего приложения, которое хранится в классе .Application, довольно часто прерывается, даже если стек Activity явно остается нетронутым. Чтобы решить эту проблему, все мои Activity должны быть в состоянии изящно справляться с глобальным состоянием, которое больше не присутствует, когда они в следующий раз перейдут на передний план, и в таком случае запускать перестройку глобального состояния. - person Trevor; 30.07.2012
comment
У меня есть интересное дополнительное наблюдение: пока мое приложение находится в фоновом режиме, его .Application (и, предположительно, процесс), кажется, циклически завершается, а затем создается повторно, в зависимости от того, что еще делает телефон. Так что, если телефон, например, воспроизводит музыку, если у меня есть Toast, чтобы указать .Application создание экземпляра, я часто вижу Toast. Это происходит с моим HTC One X, который я считаю очень хорошим тестовым устройством для такого рода поведения, потому что One X известен тем, что не хватает памяти и даже иногда убивает программу запуска, чтобы освободить оперативную память! - person Trevor; 30.07.2012
comment
Кроме того, я могу только предположить, что циклическое уничтожение и повторное создание экземпляра .Application моего приложения - это система, пытающаяся улучшить взаимодействие с пользователем, снова готовя любые процессы, которые она должна была убить ранее из-за нехватки оперативной памяти. Это заставило меня понять, что начинать любую длительную работу по восстановлению глобального состояния с точки .Application создания экземпляра - плохая идея. - person Trevor; 30.07.2012

Вы можете протестировать сценарий с помощью killing the process вашего запущенного приложения.

Шаг 1. Откройте приложение и нажмите кнопку Home, чтобы скрыть его в фоновом режиме.

Шаг 2. Вызов adb shell

Шаг 3. Введите команду su (вы должны получить разрешение ROOT, чтобы завершить процесс)

Шаг 4. ps (перечислите все идентификаторы запущенных процессов и найдите свой)

Шаг 5. kill 1234 (предположим, что ваше приложение работает в процессе 1234)

Шаг 6. Затем вернитесь к своему устройству и снова щелкните значок запуска. Вы можете обнаружить, что последнее действие в стеке действий открыто снова. Вы также можете обнаружить, что для действия вызывается метод onRestoreInstanceState().

person Darren Shen    schedule 27.11.2013

Короче: делайте инициализацию в YourApplication.onCreate, а не в каком-нибудь LaunchActivity

Документы для проверки:
- Процессы и потоки < br> - Руководства по API> Действия

Безопасно ли полагаться на активность запуска для инициализации класса Application?

Да, если вы помните, что приложение может существовать дольше, чем действие, и действие может быть уничтожено и воссоздано. Я не уверен, что намерение воскресит Activity: ЗАПУСК или ПРОСМОТР (для сценария, когда активность была убита как слишком тяжелая, в то время как к приложению была привязана долго работающая служба)

Существуют ли случаи, когда класс Application может быть воссоздан без создания действия Launch?

да, если последнее видимое действие не было LaunchActivity - проверьте жизненный цикл приложения Android и использование статики

Возможно ли, что процесс был остановлен, пока телефон спал, и при пробуждении телефона класс Application был воссоздан, верхняя активность в стеке была возобновлена, но операция запуска. OnCreate не была запущена, поэтому класс Application не был инициализирован?

Если бы было запущено несколько разных действий A, B, C и весь процесс был убит, тогда я думаю, что ОС Android хороша только с созданием действий Application и C, в то время как A и B будут повторно созданы при доступе, то есть при возврате к их.

Можно ли предположить, что экземпляр класса Application будет существовать до тех пор, пока процесс,

да

и что когда создается класс Application, это эквивалентно «перезапуску» приложения, т.е. начать с нового стека действий (и первое действие в стеке - это действие запуска)?

Я не уверен, что при перезапуске активность запуска будет вызываться первой, но последней, то есть той, которую должен увидеть пользователь.

person Paul Verest    schedule 05.02.2015

«Я столкнулся с исключительной ситуацией с нулевым указателем при доступе к переменной в классе Application при возобновлении работы приложения»

Проверьте эту ссылку .. http://www.developerphil.com/dont-store-data-in-the-application-object/

person Tamal Samui    schedule 06.12.2016