управление памятью Android в жизненном цикле активности - PullRequest
23 голосов
/ 15 февраля 2011

Мой вопрос немного сложен.

Я хочу понять, как приложение обрабатывает ресурсы (особенно изображения для фона, кнопок и т. Д.) При запуске Activity, а затем приостановке.

Например, я запускаю действие A, оно показывает все изображения на экране, съедает его память, затем запускается другое действие B и A приостанавливается.Что происходит со всеми изображениями, ресурсами и т. Д.?Когда они будут освобождены?Как я могу взять их под контроль?Разве я не должен хранить активность А в памяти и удалять ее из стека активности?

Если вам нужны какие-либо разъяснения по моим вопросам, пожалуйста, напишите мне!

Заранее спасибо!Danail

Ответы [ 5 ]

21 голосов
/ 19 февраля 2011

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

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

В конце концов, когда вы абсолютно уверены, что вам нужно что-то сделать, чтобы уменьшить использование памяти, вы можете провести некоторую оптимизацию памяти. Например, вы можете сохранить объекты, потребляющие память (например, большие изображения), в локальное хранилище в onStop() и загрузить их в onStart(). Я думаю, что использование onPause() / onResume() для этой цели - плохая идея, потому что активность частично или даже полностью видна.

Теоретически вы можете даже уничтожить все свои виджеты в onStop() и восстановить их в onStart(), но это может сделать ваше приложение слишком медленным. И, конечно же, в этом случае сохранение состояния должно осуществляться вами.

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

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

10 голосов
/ 24 февраля 2011

Хорошо, у нас следующая ситуация:

A > onCreate
A > onStart
A > onResume
A > Use up a load of memory (A could even use up too much and crash)
A > Launch activity B
B > onCreate
A > onPause
B > onStart
A > onStop
B > onResume
B > Use up a load of memory 

Если B использует достаточно памяти, система Android прекратит действие A (вы заметите, что методы onPause и onStop для A уже вызванытак что ему уже дан шанс сохранить его состояние)

Если вы затем нажмете кнопку «Назад», система Android просто снова запустит действие А (и, если оно умное, запомнит свое последнее состояние), то это будет выглядеть такс пользователем ничего не происходило.

Так что, чтобы быть немного яснее: если вы начнете B, а затем закончите A, B по существу просто заменит A в стеке действий, а нажатие кнопки Back в действии B просто завершит работу.ваше и приложение и не возвращаются к занятию A.

Если, с другой стороны, вы начинаете B без завершения A, то нажатие кнопки «Назад» в B приведет к назад к A. Пока действие A находится в фоновом режиме, его можно убить, чтобы восстановить память, но Android будет воссоздавать его по мере необходимости, когда пользователь перемещается постек действий.

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

3 голосов
/ 19 февраля 2011

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

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

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

2 голосов
/ 18 февраля 2011

Задолго до того, как ответить на ваши вопросы, я должен обсудить некоторые факты.

  1. В соответствии с жизненным циклом Деятельности, если мы позвоним finish(), тогда onStop()и, наконец, onDestroy(), который разрешает эту операцию для сборки мусора и удаляет ее из стека активности Android.

  2. Android поддерживает кэш Drawable для разработки и отображения действия на экране.Поэтому, если вы отключите извлекаемый кэш в Activity onCreate().

Поэтому лучше всего отключить извлекаемый кэш на onCreate следующим образом:

 LinearLayout v = (LinearLayout) findViewById(R.id.mainLayout);
        v.setDrawingCacheEnabled(false);

и звонить finish(); на onPause();

0 голосов
/ 17 февраля 2011

У вас очень мало контроля над памятью при написании кода Java.Это хорошо для большинства случаев.На самом деле большинству приложений не нужно беспокоиться о памяти.

Чтобы ответить на ваш вопрос, весь объект для действия A все еще будет в памяти, когда он будет приостановлен.VM запустит GC, когда ему понадобится ресурс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...