#android #memory #android-activity #native #lifecycle
#Android #память #android-активность #родной #жизненный цикл
Вопрос:
В моем приложении есть возможность иметь бесконечный стек активности. Сценарий заключается в том, что вы начинаете с страницы одного пользователя, на которой есть список людей, которые являются «друзьями» этого пользователя. Затем вы можете щелкнуть друга, чтобы перейти на его страницу, которая выглядит точно так же, как предыдущая, где затем вы можете нажать на другого друга, чтобы перейти на его страницу, и так далее…
Большая проблема, с которой я сталкиваюсь, — это бесконечная собственная куча. Я считаю, что я добавляю в эту кучу каждый раз, когда представление раздувается. После нескольких итераций я постоянно получаю ошибки ООМ, поэтому мне нужно найти какое-то решение. Хитрость в том, что я хочу сохранить последние несколько действий как минимум для навигации по некоторой истории.
Лучшее, что я могу придумать, это отслеживать стек действий, а затем начинать завершать действия, когда он достигает определенной точки. Звучит ли это как надежный подход, или даже дальше, может ли кто-нибудь указать мне на реализацию того или иного подхода?
Спасибо
Редактировать:
Стек очень прост. Нажмите на список (друга), перейдите на его страницу. При этом используется обычный вызов startActivity с намерением перейти на ту же страницу, на которой вы находитесь, и дополнительный вызов intent с идентификатором пользователя, который затем вызовет базу данных или удаленный вызов api для получения данных пользователя.
Кроме того, чтобы следить за Dalvik vs Native, я регулярно проверяю дамп meminfo во время навигации. Я сохраняю кучу dalvik как можно меньше, очищая ресурсы в onStop. Собственная куча растет намного быстрее. У меня нигде нет жестких ссылок на растровые изображения, но довольно много чертежей на экране из inflations. Приведут ли эти чертежи к тому, что Android в конечном итоге убьет мою активность? Насколько я могу судить, они просто приводят к ООМ, и ни одна из моих действий не уничтожается превентивно.
Если бы я мог вручную уничтожить свои действия вместо того, чтобы просто останавливать их (как утверждает Android при нехватке памяти), и сохранить уничтоженную активность в стеке с сохраненным состоянием, это было бы идеально.
отредактируйте еще раз:
другой ключ заключается в том, что в этих действиях будут другие действия, смешанные с ними, например
пользователь -> пользователь -> действие a -> пользователь -> действие b -> пользователь
вот почему я хочу использовать встроенный стек, чтобы я знал, когда мне нужно перейти к пользовательскому действию, а когда нет.
Комментарии:
1. как именно вы реализуете свой «стек» пользовательских страниц?
Ответ №1:
как насчет того, чтобы выполнить это действие singleInstance
, перехватить KeyEvent .KEYCODE_BACK, создайте собственный стек кнопок возврата для этого действия
я привел здесь несколько примеров:
Комментарии:
1. хорошая идея (и за нее проголосовали), однако мои потребности немного сложнее. Кое-что, о чем я забыл упомянуть, это то, что к этим действиям будут примешаны другие действия, отредактированные выше, чтобы отразить это
2. загрузите новую версию (из того же источника)… я забыл добавить
setIntent(intent);
public void onNewIntent(Intent intent)
(без этого, если вы измените ориентацию, вы потеряете backstack)
Ответ №2:
Я не думаю, что проблема с ООМ, с которой вы столкнулись, связана с количеством открытых вами действий. Android должен уничтожать любые старые действия в фоновом режиме по мере увеличения объема памяти. Затем эти действия будут просто воссозданы, когда пользователь вернется обратно через стек задач.
Использовали ли вы такой инструмент, как MAT (инструмент анализа памяти), для проверки того, что вы выделили во время выполнения вашего приложения. Я подозреваю, что у вас может быть утечка памяти или что вам, возможно, придется быть умнее в распределении памяти.
Комментарии:
1. Я использовал MAT и тоже был довольно осторожен в высвобождении ресурсов onStop. Наблюдая за дампом meminfo по мере углубления, как native, так и dalvik повышаются. Будет ли система также прекращать действие из-за проблемы с собственной кучей? Я думал, что это отдельно…
2. Что ж, я бы ожидал, что и native, и dalvik будут работать до тех пор, пока не будет запущен GC. Если большая часть вашей памяти выделена на собственной стороне, я думаю, вы правы в своем предположении, что Dalvik не будет реагировать на это. Похоже, вы выполняете большую часть работы на родной стороне. Вы уверены, что ваша очистка работает правильно, потому что onStop должен вызываться для действия при переходе к следующему в стеке.
3. Моя очистка работает, но она может быть недостаточно тщательной. Я очищаю списки и корзины списков, чтобы избавиться от строк, но другие представления остаются нетронутыми, то есть все, что находится за пределами моего списка, сохраняет свои чертежи (кнопки, фоны, изображения заголовков и т. Д.). Я подозреваю, что именно поэтому собственная куча просто продолжает расти, каждый раз, когда она раздувает эти чертежи, они просто сидят там. Итак, как я это вижу, мне нужно либо уничтожить все мои просмотры onstop (что кажется излишним), либо регулировать размер моего стека активности. Если бы я мог видеть, что было в моей родной куче, я был бы более уверен.
4. Да, это может быть более полезно для других, если вы опубликуете больше о том, что вы делаете изначально VS в Dalvik внутри вашего вопроса, поскольку NDK действительно выходит за рамки моей компетенции. Я знаю, что вам не следует пытаться сохранять чертежи между действиями, если вы не очень осторожны в том, как вы отвязываете их от своей деятельности. Смотрите android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html говоря именно об этом вопросе.