Управление памятью Android для активности в onStop (или за кадром) - PullRequest
3 голосов
/ 12 декабря 2011

Чего я пытаюсь достичь:

  • Уменьшить использование памяти действия, которого больше нет на экране, то есть было запущено другое действие
  • Возможность этого действиявсе еще находится в стеке навигации, поэтому я предполагаю, что мне придется пересобрать то, что было уничтожено в onStop, в onStart, но не уверен, как это сделать, когда все представления / кнопки были построены с использованием layout.xml.

Ситуация:

У меня есть приложение для Android, которое имеет очень большое изображение, но эти изображения статичны на многих макетах с одинаковыми фонами, изображениями кнопок, заголовками навигации и т. Д. Это привелоМне легко создать макеты, не слишком касаясь кода, указав все imageViews, их атрибуты src и позиции в файлах layout.xml.И это прекрасно работало, его было легко запустить и запустить, однако теперь есть много сообщений о принудительном закрытии из-за превышения использования памяти.

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

Так что onDestroy не помогает мне, когда я помещаю новое действие в стек и не хочучтобы очистить то, что только что покинул экран.Но плюсом использования метода onDestroy является то, что точка входа начинается с onCreate, поэтому все представления построены правильно.Когда я использую этот метод в onStop, память get хорошо очищается, когда я начинаю новое действие, но, поскольку я уничтожил все представления и они были построены с использованием layout.xml, я не понимаю, как или что мне нужнозаново встроить onStart, если я уничтожу все в onStop, особенно учитывая, что я никогда не создавал никаких представлений в коде, поскольку все они были настроены из-за файлов layout.xml.

Основные вопросы: Как сделатьЯ очищаю память, когда начинаю новую активность?Если контексты обрабатываются правильно, то условно, что gc все равно очистит все изображения, находящиеся вне экрана, и автоматически перестроит их?

Можно ли это как-то использовать в onStop?

 @Override
protected void onDestroy() {
    super.onDestroy();

    unbindDrawables(findViewById(R.id.RootView));
    System.gc();
}

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

Ответы [ 2 ]

2 голосов
/ 12 декабря 2011

A) Использование onCreate () / onDestroy () будет выделять, когда активность попадает в стек, и нераспределять, когда активность извлекается из стека.

В) Использование onStart () / onStop () будет выделять, когда активность становится видимой, и нераспределять, когда активность невидима.

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

В вашем случае я бы переместил все из onCreate () в onStart () и все из onDestroy () в onStop ().

Кроме того, рассмотрите возможность использования this.setContentView (null) или this.setContentView (new View (this)) в onStop (), чтобы убедиться, что старые представления могут быть собраны сборщиком мусора:

  @Override
  protected void onStop() {
    super.onStop();
    View root = findViewById(R.id.RootView);
    setContentView(new View(this)) 
    unbindDrawables(root);
    System.gc();
  }
1 голос
/ 12 декабря 2011

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

Полагаю, вы предпочли бы держаться за изображения, если можете, но вы хотели бы отказаться, если системе нужны ресурсы. Если это (кеширование) - то, на что вы смотрите WeakReference - это ваш мужчина. Посмотрите эту отличную статью , которая поможет вам решить / понять.

Кроме того, я не думаю, что Android задумал нас, разработчиков, беспокоиться о том, когда представления, сгенерированные из файлов макетов, будут gc'd. Пока у вас нет сильных ссылок на представления, у вас должно быть все в порядке.

...