Подтвердить что ты не робот

Когда статические ресурсы убиты, все они убиты или могут остаться в редких случаях?

Примечание. Хотя два ответа, предоставленные до сих пор (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 где-либо еще в коде.

4b9b3361

Ответ 1

Вы должны посмотреть на это: Жизненный цикл деятельности.

enter image description here

Когда вы потеряли память, приостановленные действия будут уничтожены для освобождения памяти.

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

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

Обратите внимание на столбец "Killable" в приведенной выше таблице - для тех методов, которые отмечены как подлежащие уничтожению, после того, как этот метод возвращает процесс, в котором эта активность может быть уничтожена системой в любое время без выполнения другой строки исполняемого кода, Из-за этого вы должны использовать метод onPause() для записи любых постоянных данных (например, прав пользователя) на хранение. Кроме того, метод onSaveInstanceState (Bundle) вызывается перед тем, как помещать активность в такое фоновое состояние, позволяя вам сэкономить любое динамическое состояние экземпляра в вашей деятельности в данном Bundle, чтобы позже получить его в onCreate (Bundle), если действие необходимо воссоздать. Дополнительную информацию о том, как жизненный цикл процесса привязан к действиям, которые он размещает, можно найти в разделе "Процесс жизненного цикла". Обратите внимание, что важно сохранить постоянные данные в onPause() вместо onSaveInstanceState (Bundle), потому что последнее не является частью обратных вызовов жизненного цикла, поэтому не будет вызываться в каждой ситуации, как описано в его документации.

Ответ 2

Я думаю, что вы как-то ошибаетесь в отладке или отслеживании проблем в своем приложении.

Вот что я могу вам сказать, и что я думаю, что вы поняли неправильно:

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

У меня также был аналогичный вопрос: Перезапуск приложения - точка входа в действие