Android не завершается процесс

Памятка по жизненному циклу Android — часть I. Отдельные Activity

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

Чтобы обеспечить такое взаимодействие с пользователем, вы должны знать, как управлять жизненными циклами компонентов. Компонентом может быть Activity, Fragment, Service, класс Application и даже сам процесс приложения. Компонент имеет жизненный цикл, в течение которого он проходит через различные состояния. Всякий раз, когда происходит переход, система уведомляет вас об этом при помощи методов жизненного цикла.

Чтобы нам было легче объяснить, как работает жизненный цикл в Android, мы определили несколько сценариев (примеров из жизни), которые сгруппированы по компонентам:

Часть 1: Activity — ЖЦ одного активити (этот пост)

Диаграммы также доступны в виде шпаргалки в формате PDF для краткого ознакомления.

Примечание: эти диаграммы соответствуют поведению в Android P/Jetpack 1.0.

Следующие сценарии демонстрируют поведение компонентов по умолчанию, если не указано иное.

Если вы обнаружили ошибки в статье или считаете, что не хватает чего-то важного, напишите об этом в комментариях.

Часть 1: Activity

Одно Aсtivity — Сценарий 1. Приложение завершено и перезапущено

Будет вызван, если:

Пользователь нажимает кнопку Назад или

Вызван метод Activity.finish()

Самый простой сценарий показывает, что происходит, когда приложение с одним активити запускается, завершается и перезапускается пользователем:

Управление состоянием

onSaveInstanceState не вызывается (поскольку активити завершено, вам не нужно сохранять состояние)

onCreate не имеет Bundle при повторном открытии приложения, потому что активити было завершено и состояние не нужно восстанавливать.

Одно Aсtivity — Сценарий 2. Пользователь уходит

Будет вызван, если:

Пользователь нажимает кнопку «Домой»

Пользователь переключается на другое приложение (через меню «Все приложения», из уведомления, при принятии звонка и т. д.)

В этом случае система остановит активити, но не завершит его сразу.

Управление состоянием

Когда ваше активити переходит в состояние Stopped, система использует onSaveInstanceState для сохранения состояния приложения на тот случай, если впоследствии система завершит процесс приложения (см. ниже).

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

Одно Aсtivity — Сценарий 3. Изменение кофигурации

Будет вызван, если:

Изменена конфигурация, такие как поворот экрана

Пользователь изменил размер окна в многооконном режиме

Управление состоянием

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

Активити полностью уничтожено, но состояние сохраняется и восстанавливается при создании нового экземпляра.

Bundle в onCreate тот же самый, что и в onRestoreInstanceState .

Одно Aсtivity — Сценарий 4. Приложение приостановлено системой

Будет вызван, если:

Включён многооконный режим (API 24+) и потерян фокус

Другое приложение частично покрывает работающее приложение: диалоговое окно покупки (in-app purchases), диалоговое окно получения разрешения (Runtime Permission), стороннее диалоговое авторизации и т. д.

Появится окно выбора приложения (при обработке неявного интента), например диалоговое окно шейринга.

Этот сценарий не применим к:

Диалогам в том же приложении. Отображение AlertDialog или DialogFragment не приостанавливает базовое активити.

Уведомлениям. Пользователь, получающий новое уведомление или открывающий панель уведомлений, не приостанавливает текущее активити.

Источник

«Процесс android.process.acore остановлен»: решение проблемы

Наиболее часто ошибка возникает при попытке добавить контакт в телефонную книгу, сохранить его, изменить. Для устранения проблемы заходим в НастройкиПриложенияВсе, там находим «Хранилище контактов» (у вашего смартфона этот пункт может называться иначе, но смысл один и тот же). После этого выбираем «Стереть данные». Списка контактов вы, конечно, лишитесь, но аппарат с большой долей вероятности сможет использоваться в дальнейшем. К тому же, если у пользователя имеется аккаунт Google, то даже список контактов не пропадет.

Читайте также:  Закрыть рабочий стол андроид

Второй, более сложный и рискованный способ — изменение системного файла /system/csc/others.xml. Ваша задача — отредактировать строку: TRUE. В результате должно получиться вот что: false.
Еще раз предупреждаем, что этот способ сложен для новичков, и воспользоваться им рекомендуем только более или менее опытным пользователям.

Третий вариант решения проблемы — откат Android-устройства к заводским настройкам. Все изменения, внесенные пользователем после покупки гаджета (в том числе индивидуальные настройки) исчезнут, но для большинства это не так страшно, как необходимость вручную восстанавливать книгу контактов. Решили прибегнуть к этому способу? Берите инструкцию к своему гаджету и ищите инструкцию к пункту Recovery.

Еще одной причиной появления ошибки «android.process.acore» могут являться недавно установленные приложения для оптимизации беспроводной сети Wi-Fi. У ряда пользователей проблема решалась удалением этих приложений.

И, наконец, самый кардинальный способ: полная очистка памяти смартфона. Вы потеряете все данные, но приложение, которое генерировало ошибку, будет гарантированно удалено с Android-устройства.

Источник

Как принудительно закрыть приложение или игру на Android которая зависла

Для тех, кто впервые начинает пользоваться Android устройством непонятно, а как же закрывать запущенные приложения. Ведь в отличие от ОС Windows, к которой все привыкли, здесь нет непосредственно на экране смартфона (планшета) окна работающей программы с кнопкой для ее закрытия как в Windows.

В этом материале для начинающих пользователей мы расскажем, как закрыть приложение на Андроид.

Как принудительно закрыть приложения и игры на смартфоне Android: распространенные способы

Андроид едва ли не с первых дней существования получил многозадачность. А если несколько программ могут работать одновременно, то у пользователя должна иметься возможность какие-то из них закрывать. Или даже отключать, но об этом мы поговорим чуть ниже. Закрытие приложения подразумевает собой его выгрузку из оперативной памяти, заодно программа перестанет нагружать процессор

Далее я расскажу вам о всех способах которые помогут закрыть вам приложения работающие в фоновом режиме вашего Android устройства.

Способ первый: При помощи функции последние приложения

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

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

  1. Запустите меню последних приложений. В зависимости от вашего устройства, есть разные способы доступа к этому меню. Некоторым из вас нужно слегка провести пальцем вверх от нижней части главного экрана, коснуться квадратного значка в нижней части экрана или выбрать нужную кнопку на телефоне.
  2. Найдите приложение, которое хотите закрыть. Проведите пальцем вверх или вниз (влево или вправо на некоторых устройствах), чтобы найти приложение, которое вы хотите закрыть.
  3. Нажмите, удерживайте и проведите пальцем, чтобы закрыть приложение. Если ваши приложения находятся в горизонтальном списке, вам нужно провести вверх, чтобы сделать это. Но если ваши приложения находятся в вертикальной ориентации, проведите пальцем влево или вправо, чтобы закрыть приложение.
  4. Если вы хотите закрыть все запущенные приложения, есть функция «ЗАКРЫТЬ ВСЕ» или «ОЧИСТИТЬ ВСЕ», чтобы вам не приходилось закрывать все из них вручную

Как принудительно остановить работу приложений – пошаговая инструкция

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

Для того, чтобы это сделать воспользуйтесь следующей инструкцией:

  1. Перейдите в меню приложений. Перейдите к настройкам в панели уведомлений или в панели приложений. Прокрутите вниз и нажмите на приложения.
  2. Выберите приложение, которое вы хотите закрыть. Измените меню и покажите все приложения на вашем устройстве. Оттуда найдите приложение, которое вызывает проблемы, и выберите его.
  3. Выберите Force Stop. На странице приложения, на которой вы находитесь, найдите кнопку «Force Stop» и выберите кнопку. Если вы решили, что приложение вам не нужно, вы также можете удалить его оттуда.
  4. Подтвердите. Как только вы убьете работающее приложение, оно не перезапустит и не запустит свои процессы, если вы не запустите приложение самостоятельно. Таким образом, приложение не будет продолжать вас беспокоить, даже если вы не удалили его.

Источник

Android Process: Я тебя породил, я тебя и …

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

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

Читайте также:  Андроид сброс рекламного идентификатора

Ни для кого не секрет, что процесс может быть убит системой. А вы интересовались, реально ли сымитировать это? Можно попробовать“натравить” систему на свое приложение, запуская кучу других приложений, съедающих знатный кусок памяти, а затем надеяться, что система таки снизошла до нас убив нужное приложение. Прямо какой-то шаманизм получается, а это стезя админов, но никак не программистов. Меня заинтересовало, как можно легко и быстро убить приложение, да так, будто это сделала система для освобождения ресурсов. Ведь если получится повторить подобное поведение в “лабораторных условиях”, можно будет отлавливать множество ошибок ещё на стадии разработки, либо с лёгкостью воспроизвести их для выявления причин.

Как оказалось, нужный механизм уже имеется в SDK, и это… барабанная дробь… Кнопка «Terminate Application».

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

Для того, чтобы воспроизвести ситуацию с возобновлением работы приложения после его полной остановки, нужно проделать следующую последовательность действий:

  1. Используя Android Stidio запустить приложение;
  2. Свернуть приложение нажатием кнопки «Home»;
  3. В Android Studio, перейти на вкладку Android, выбрать приложение и нажать кнопку «Terminate Application»;
  4. Развернуть свернутое приложение.

Если Activity не совсем корректно обрабатывает восстановление после уничтожения, вы сразу это заметите. В лучшем случае оно упадёт, в худшем зависнет.

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

Ситуация 1: Статик — это не надёжно

Как видно из кода, в первой Activity разработчик решил не “заморачиваться” и поместил данные в статические переменные. Это весьма соблазнительно, когда нужно передать достаточно неординарный объект, не поддающийся простой сериализации. Над второй Activity он тоже не долго думал и не сделал проверки на нул. Зачем, когда первая Activity всё уже сделала?

Проделываем описанную ранее последовательность по корректному уничтожению процесса на второй Activity. Приложение падает.

Что случилось?
Проблема тут не в отсутствии проверки на null. Самая страшная проблема — это потеря пользовательских данных. Статические объекты не должны быть хранилищем данных, особенно если это их единственное место. Касается это как обычных переменных так и синглтонов. Так что если в статике хранится что-то важное, будьте готовы это важное потерять в любой момент.

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

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

Сейчас я не собираюсь выяснять, что тут правда а что домыслы. В любом случае это лишь снижает вероятность потери статик ссылки но ни как не спасает от остановки процесса. Остановка процесса приведет к полному уничтожению класслоадера, а вместе с ним и уничтожению всех классов, включая класс Application.

Ситуация 2: setRetainInstance как решение всех проблем

Такая реализация — стойка к любым вращениям экрана. Все будет работать как часы. До поры до времени…
Применим последовательность действий для хитрого уничтожения процесса, когда диалог открыт. При разворачивании ничего не произойдет. Однако, при вызове invokePersonChoose приложение вылетит с NullPointerException.

Что случилось?
setRetainInstance(true) не позволяло диалогу уничтожиться. После уничтожения процесса диалог все-таки был уничтожен. Activity восстанавливает фрагмент насколько это возможно. К сожалению, слушатель не восстанавливается, так как он был установлен совершенно в другом месте для совершенно другого объекта. Когда в диалоге, в методе invokePersonChoose, происходит обращение к слушателю, выбрасывается исключение. И беда тут не в отсутствии проверки на null. Поставить проверку на null без должной реакции на пустую ссылку будет еще более худшим решением.

Читайте также:  Звуки уведомлений для андроид где находятся

Что делать?
В интернете описана куча способов передачи сообщений из фрагмента в Activity. К сожалению, не все из них правильные. Следующий способ правильный и один из моих любимых:

    Activity реализует нужный интерфейс:

Единственное, что не стоит забывать, Activity может быть уже уничтожена когда дело дойдет до отправки сообщения. Поэтому обязательно проверьте добавлен ли фрагмент на Activity.
По мимо Activity можно использовать родительский фрагмент или Target фрагмент.

Еще пара слов про setRetainInstance
Замечу, это лишь частный случай с setRetainInstance. Количество проблем которые он может скрыть(а не решить) немного больше. Вместе со слушателями также теряются и все остальные переменные. Все, что не было сохранено в методе onSaveInstanceState, будет потеряно.
Также, он скрывает проблему когда класс диалога анонимный. Допустим, в момент создания нового объекта диалога, переопределен какой либо метод, в этом случае создастся объект анонимного класса.

Если этот диалог будет уничтожен и система попытается его восстановить выбросится исключение ClassNotFoundException.

Ситуация 3: Разорванные нити

Если запустить этот код и не дожидаясь его завершения свернуть приложение, а затем вырубить процесс, то при разворачивании ничего не предвещает беды, приложение не падает, а диалог показывается. Ждём немножко… Ещё ждём… Потом ещё ждём… Диалог не закрывается, хоть и должен был сделать это уже давно.

Что случилось?
При уничтожении процесса останавливаются все его потоки, а при восстановлении запускается только главный поток. Так что если ваш поток работает слишком долго, будьте готовы к тому, что он будет остановлен. Причём не обязательно делать что-то долго, на эти грабли можно наступить и при использовании wait notify. Особенно забавно будет, если в качестве объекта для блокировки использовать public static final Object, ведь мы то уже знаем, что статик объекты не исключение при уничтожении процесса.

Что делать?
Если задача занимает много времени вынести ее в отдельный сервис и запустить в новом процессе, плюс вывести foreground Notification, иначе процесс все равно будет убит. В случае с wait notify все немного сложнее и зависит от конкретной ситуации. Вообще, тема работы с потоками достаточно обширна, и давать какой-то конкретный совет тут неуместно. Разве что не усложнять и не лезть в дебри, из которых не сможешь вылезти.

Ситуация 4: Письмо в никуда

Для того чтобы первая Activity не уничтожалась при поворотах экрана, в файл манифеста добавлены configChanges.

Во второй Activity есть кнопка, нажатие по которой шлет сообщение для смены цвета.

При возвращении на первую Activity цвет View будет изменен.

Однако, если перейти на вторую Activity, свернуть приложение, убить процесс, а затем развернуть приложение, случится кое-что не предвиденное. Сколько бы раз вы не нажимали на кнопку смены цвета, при возвращении на первую Activity ее View будет белоснежной.

Что случилось?
Не смотря на то, что стек активностей сохранился, после разворачивания приложения была восстановлена только вторая Activity. Фактически, сообщения о смене цвета уходили в никуда. Так как на тот момент не существовало объектов, подписанных на это событие. При возвращении на первую Activity она была восстановлена, но подписываться на событие смены цвета было уже поздно.

Что делать?
Первым делом нужно уяснить главное — если вы работаете с одной Activity, остальные для нее не существуют. Если нужно донести какую либо информацию, используйте предназначенный для этого setResult. Еще не следует слепо полагаться на жизненные циклы. Как видно из примера, если Activity 1 запустила Activity 2 то это еще не значит, что метод onCreate первой Activity был выполнен.
Также замечу, этот пример показывает не только на проблемы со стеком активностей, но и проблемы со всем, что связано с посылкой сообщений. Исключением будут только BroadcastReceiver-ы, прописанные в манифесте, либо запланированные через AlarmManager. Все остальное не дает 100% гарантии на доставку сообщения адресату.

Заключение

“Бывалым кодерам” эти ситуации могут показаться очевидными, а примеры на столько не естественными, что просто воротит. Однако, все мы когда-то начинали с нуля и писали код от которого сейчас было бы стыдно. Знай я об этих граблях в самом начале своего пути, шишек на лбу было бы меньше. Надеюсь, эта статья поможет наставить на путь истинный большое количество начинающих Android программистов. От “Бывалых” буду рад увидеть комментарии. А еще лучше если вы дополните список или напишете, помогла ли эта статья в ловле багов из разряда “Как?! Такого не может быть!”.

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

Источник

Оцените статью