Проблема:
У меня есть приложение для Android, которое позволяет пользователю просматривать профиль пользователя ViewProfileFragment
. Внутри ViewProfileFragment
пользователь может щелкнуть изображение, которое приведет его к StoryViewFragment
, где появятся фотографии разных пользователей. Можно щелкнуть по фотографии профиля пользователя, которая перенесет их в другой экземпляр ViewProfileFragment
с новым профилем пользователя. Если пользователь повторно нажимает на пользовательские профили, щелкает изображение, которое выводит их в галерею, затем нажимает на другой профиль, который фрагменты складываются в память, быстро вызывая страшный OutOfMemoryError
. Вот диаграммный поток того, что я описываю:
UserA нажимает на профиль Боба. Внутри профиля Bob UserA нажимает на ImageA, беря его в галерею фотографий различных пользователей (включая Боба). UserA нажимает на профиль Sue, затем на одном из ее изображений - повторы процесса и т.д. И т.д.
UserA -> ViewProfileFragment
StoryViewFragment -> ViewProfileFragment
StoryViewFragment -> ViewProfileFragment
Итак, как вы можете видеть из типичного потока, в стопке складок много экземпляров ViewProfileFragment
и StoryViewFragment
.
СООТВЕТСТВУЮЩИЙ КОД
Я загружаю их в виде фрагментов со следующей логикой:
//from MainActivity
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.activity_main_content_fragment, fragment, title);
ft.addToBackStack(title);
ЧТО Я ПОЛУЧИЛ
1) Я специально использую FragmentTransaction
replace
, чтобы метод onPause
запускался, когда имеет место replace
. Внутри onPause
Я пытаюсь освободить столько ресурсов, сколько могу (например, очистка данных в адаптерах ListView
, "обнуление" переменных и т.д.), Так что, когда фрагмент не является активным фрагментом и нажимается на backstack будет больше освобожденной памяти. Но мои усилия по освобождению ресурсов - это лишь частичный успех. Согласно MAT, у меня все еще много памяти, которая потребляется GalleryFragment
и ViewProfileFragment
.
2) Я также удалил вызов addToBackStack(), но, очевидно, это плохой пользовательский интерфейс, потому что они не могут вернуться назад (приложение просто закрывается, когда пользователь нажимает кнопку "Назад" ).
3) Я использовал MAT для поиска всех объектов, которые занимают много места, и я использовал их разными способами внутри методов onPause
(и onResume
), чтобы освободить ресурсы, но они по-прежнему значительны по размеру.
4) Я также написал цикл for в обоих фрагментах onPause
, который устанавливает все мои ImageViews
в null, используя следующую логику:
for (int i=shell.getHeaderViewCount(); i<shell.getCount(); i++) {
View h = shell.getChildAt(i);
ImageView v = (ImageView) h.findViewById(R.id.galleryImage);
if (v != null) {
v.setImageBitmap(null);
}
}
myListViewAdapter.clear()
ВОПРОСЫ
1) Могу ли я игнорировать способ позволить фрагменту оставаться на задней стороне, но также освобождать его ресурсы, так что цикл .replace(фрагмент) не съедает всю мою память?
2) Каковы "лучшие практики", когда ожидается, что много фрагментов может быть загружено в заднюю часть? Как разработчик правильно справляется с этим сценарием? (Или логика в моем приложении по своей сути ошибочна, и я просто делаю это неправильно?)
Любая помощь в мозговом штурме решения этого будет очень признательна.