В моем приложении для Android (написанном на kotlin) я хотел бы сохранить некоторые данные, когда моя активность будет уничтожена. Но у меня есть проблема. Я провел исследование и обнаружил, что вызов методов onDestroy() и onStop() не гарантируется. Таким образом, практически моя деятельность может быть уничтожена без вызова метода onDestroy(), что было бы для меня катастрофой. Пожалуйста, есть ли у кого-нибудь мягкое решение этой проблемы?
Вот черт. Я только что узнал, что для устройств с версией 4.0 и ниже функция onStop() не гарантируется, а для версий выше 4.0 — да. Хорошо, круто, это практически все устройства :)
но @BömachtBlau, чем является использование метода onDestroy, если он никогда не будет гарантированно вызван. Я не вижу ни одного сценария, который я бы использовал... Это выглядит так небезопасно, и мне не нравится небезопасность в программировании...
onDestroy() вызывается, например. когда действие будет уничтожено из-за изменения конфигурации
С годами все время от времени меняется — я просто перечитываю это руководство, чтобы быть уверенным, как обстоят дела сегодня.
Да, это то, что делает ОС. Но мы, как программисты, никогда не должны переопределять и использовать этот метод, поскольку он небезопасен? Это то, что я имел в виду
Да конечно. Может быть, когда-нибудь он станет безопасным, как onStop стал безопасным с API 4.0 и выше.
Хорошо, спасибо за разговор и ваше время, вы мне помогли
В руководстве говорится: «Обратный вызов onDestroy () должен освободить все ресурсы, которые еще не были освобождены более ранними обратными вызовами, такими как onStop ()» ... поэтому, если действие все еще должно что-то удерживать, сейчас самое время. .. но я согласен, вам не нужно переопределять onDestroy() в большинстве случаев.... и пожалуйста :)
Вы правы насчет onDestroy()
не рассчитывайте на то, что этот метод будет вызываться как место для сохранения данных!
Для сохранения состояния вы должны использовать onPause()
, onSaveInstanceState()
или
onStop() — вызывается, как только ваша активность больше не видна пользователю.
Некоторая дополнительная информация:
Цель переопределения onDestroy
состоит в том, чтобы очистить утечку ресурсов, например, что-то, что использует собственную память или порожденный поток, который удерживает ссылки на объекты. Он никогда не станет «безопасным», как вы предложили в комментариях, потому что его использование в качестве крючка для сохранения состояния не является его целью. Причина, по которой его вызов не гарантируется, заключается в том, что если ОС полностью закрывает ваше приложение, вся куча памяти для вашего приложения освобождается, и в этом случае его вызов будет излишним.
Большинству приложений никогда не потребуется переопределять его, потому что большинство приложений не выделяют память напрямую, и есть лучшие методы для обработки асинхронной работы, чем непосредственное создание потоков.
Я вас понимаю, вы хотите сказать, что лучше всего использовать его, например, для отмены регистрации приемников, слушателей и т. д., чтобы избежать утечек памяти. Это совершенно нормально. Но в Android часто бывают случаи, когда вы должны выполнить какое-то действие, когда Activity уничтожается, и это те случаи, которые меня сбивают с толку. Вы уверены, что единственная причина, по которой onDestroy() не может быть вызвана, заключается в том, что ОС убила все мое приложение?
Это единственная ситуация, описанная в документации, но она сформулирована таким образом, что это не обязательно гарантирует. Как правило, при уничтожении действия необходимо удалить все, что вы настроили в onCreate()
, например, отменить регистрацию слушателей, и в этом случае можно сделать это в onDestroy()
. Например, если вы настроили SharedPreferencesOnChangedListener в onCreate()
, имеет смысл отменить его регистрацию в зеркальном методе onDestroy()
.
Но в современных рекомендуемых практиках Android большинство подобных вещей будет в ViewModel. Это одна из причин, по которой я сказал, что переопределение onDestroy()
не является обычным явлением. Я не уверен, какие еще вещи вы думаете о том, что может потребоваться сделать, когда действие уничтожено.
Например, в приложении моей компании есть PlayGameActivity, в котором мы запускаем игру. Мы переопределяем метод OnDestroy(), чтобы мы могли вызвать client.refresh() для обновления нашего баланса, когда мы закончим играть в игру и вернемся к другому действию. Так что это не случай «отмены регистрации прослушивателя», но для этого нам все же нужен OnDestroy. Также я хотел бы спросить вас. Если у нас есть фрагмент, правда ли, что мы можем использовать onDetach() в подобных ситуациях (гарантированно ли он вызывается?) и выполнять всю нашу работу здесь.
onPause
и onStop
всегда гарантированно вызываются (кроме случаев сбоя). В ситуации нехватки памяти Android может закрыть ваше приложение, когда оно находится в фоновом режиме, поэтому вы не можете полагаться на onDestroy
для сохранения чего-либо. Вы никогда не знаете наверняка, когда ваше приложение перейдет в фоновый режим (onStop
), что оно вернется без предварительного закрытия, поэтому вы должны предположить, что это может быть, и сохранить в onPause или onStop, чтобы быть уверенным. Я не уверен в гарантиях жизненного цикла фрагмента.
Ооо, так что, когда мое приложение находится в фоновом режиме, а ОС Android отключает его, OnDestroy() не будет вызываться? Теперь я понял, что вы хотите сказать, это проясняет ситуацию. Хорошо, спасибо за ваши объяснения, вы помогли мне разобраться в этом вопросе!
Где вы прочитали, что вызов onStop() не гарантируется?