Когда статические ресурсы убиты, все они убиты или могут остаться в редких случаях?
Примечание. Хотя два ответа, предоставленные до сих пор (6 сентября), интересны, к сожалению, они не затрагивают вопрос.
Одно из моих тестовых устройств для Android - это HTC One X. Это устройство известно часто для того, чтобы часто запускать фоновые приложения (даже включая запуск, наиболее беспричинно), поскольку он имеет тенденцию жить на грани в плане распределения ОЗУ, предположительно из-за HTC bloatware. Однако для моих целей это было чрезвычайно полезно, поскольку оно помогло выявить эффекты различных ситуаций с низкой памятью и позволить мне улучшить мое приложение, чтобы справляться с такими событиями. Например, одна из вещей, которую я узнал, заключается в том, что ресурсы Application
и другие ресурсы static
могут быть убиты, даже если стопка Activity
сохраняется. Таким образом, чтобы обеспечить хороший пользовательский интерфейс, стоп-кадр может оставаться даже при том, что один процесс, запускающий приложение, и все static
он держится, ушел. По этой причине мое приложение теперь очень прочное с точки зрения грамотной проверки состояния и, при необходимости, повторной инициализации данных "Singleton", необходимых для возобновления любого Activity
.
Чтобы перейти к моему конкретному вопросу, я наблюдал редкий симптом, который, по проверке кода, по моему мнению, мог быть вызван только членом static
одного класса, который был убит, а затем повторно инициализирован, тогда как другой статический ресурс в одном из моих классов библиотеки не был повторно инициализирован. Я понимаю, что такая зависимость между двумя отдельными ресурсами static
представляет собой плохую конструкцию с моей стороны, и я буду реорганизовать ее, чтобы избежать этого. Тем не менее, я хотел бы знать, могу ли я быть прав в своем анализе, т.е. Возможно ли иметь место, где хранится стопка назад, но только некоторые ресурсы static
погибают, особенно в каждой библиотеке/пакет?
Изменить 1. Я расскажу немного больше о двух соответствующих классах.
Класс 1 - класс, который мы назовем Controller
. Он не используется как Singleton, но содержит static
Map
данных, которые будут распространены во всех экземплярах. Он инициализирован так:
private static Map<String, String> sSomeMetaData;
static {
sSomeMetaData = new HashMap<String, String>();
}
Далее, у меня есть класс под названием MyFlyweightFactory
. Этот класс живет в отдельной библиотеке. Этот класс является Singleton:
private static MyFlyweightFactory instance = new MyFlyweightFactory();
public static synchronized MyFlyweightFactory getInstance(){
return instance;
}
private MyFlyweightFactory(){ }
TreeMap<String, MyParserRenderer> images = new TreeMap<String, MyParserRenderer>();
Теперь, вот зависимость. Класс factory имеет метод getter для получения определенного именованного объекта изображения, который создается путем разбора файла из файловой системы. Если factory не запрашивается для этого изображения с момента инициализации factory, он анализирует его из файла (это фактически моя библиотека анализатора SVG). Изображение анализируется в объект MyParserRenderer
. Когда это разбор изображения происходит, factory также заполняет некоторые данные в элементе Controller
class 'sSomeMetaData
. Все изображения, которые удерживает factory, хранятся в элементе images
TreeMap
, который вы видите выше. Таким образом, эти изображения являются нестационарным членом экземпляра static
Singleton factory.
Редкая проблема в том, что экземпляры Controller
обнаруживают, что sSomeMetaData
пуст, хотя я знаю, что MyFlyweightFactory
предоставил некоторые объекты из своего Map
. Вероятно, это могло произойти только в том случае, если intance MyFlyweightFactory
остался вокруг и, следовательно, не нуждался в повторном анализе объектов изображения (это означает, что он больше не будет заполнять sSomeMetaData
), но в между тем инициализатор static
Controller
с тех пор выполнен снова. Я могу подтвердить, что sSomeMetaData
не является clear()
ed где-либо еще в коде.
Ответы
Ответ 1
Вы должны посмотреть на это: Жизненный цикл деятельности.
![enter image description here]()
Когда вы потеряли память, приостановленные действия будут уничтожены для освобождения памяти.
Следовательно, почему вы должны попытаться объяснить это в каждой ситуации, которую вы должны воссоздать.
Это не целое приложение, а на основе активности. Таким образом, он начнет убивать действия, которые, по его мнению, менее важны. Некоторые действия могут быть затронуты, а другие нет, в том же приложении.
Обратите внимание на столбец "Killable" в приведенной выше таблице - для тех методов, которые отмечены как подлежащие уничтожению, после того, как этот метод возвращает процесс, в котором эта активность может быть уничтожена системой в любое время без выполнения другой строки исполняемого кода, Из-за этого вы должны использовать метод onPause() для записи любых постоянных данных (например, прав пользователя) на хранение. Кроме того, метод onSaveInstanceState (Bundle) вызывается перед тем, как помещать активность в такое фоновое состояние, позволяя вам сэкономить любое динамическое состояние экземпляра в вашей деятельности в данном Bundle, чтобы позже получить его в onCreate (Bundle), если действие необходимо воссоздать. Дополнительную информацию о том, как жизненный цикл процесса привязан к действиям, которые он размещает, можно найти в разделе "Процесс жизненного цикла". Обратите внимание, что важно сохранить постоянные данные в onPause() вместо onSaveInstanceState (Bundle), потому что последнее не является частью обратных вызовов жизненного цикла, поэтому не будет вызываться в каждой ситуации, как описано в его документации.
Ответ 2
Я думаю, что вы как-то ошибаетесь в отладке или отслеживании проблем в своем приложении.
Вот что я могу вам сказать, и что я думаю, что вы поняли неправильно:
Когда ваше приложение уничтожается Android
, потому что ему нужны ресурсы, ваш класс Application
будет также "уничтожен/остановлен" и backstack
сохранен. При повторном запуске приложения ваш конкретный класс Application
будет "заново создан" (будет вызываться onCreate()
), и ваш задний стек Activity
также будет воссоздан, что означает, что последний Activity
, который был виден пользователю, будет воссоздан. Итак, в основном, что происходит в вашем приложении, - это ожидаемое поведение. Почему некоторые члены библиотеки не получают повторной инициализации... Я не могу понять это.
У меня также был аналогичный вопрос: Перезапуск приложения - точка входа в действие