ПРОБЛЕМА:Android Фрагменты на Backstack занимают слишком много памяти
У меня есть Android-приложение, которое позволяет пользователю просматривать в профиле пользователя ViewProfileFragment
. Внутри ViewProfileFragment
пользователь может нажать на изображение, которое приведет его к StoryViewFragment
, где появятся фотографии различных пользователей. Можно щелкнуть по фотографии профиля пользователя, которая перенесет их в другой экземпляр ViewProfileFragment
с профилем нового пользователя. Если пользователь повторно нажимает на профили пользователя, кликает изображение, которое переносит их в галерею, затем нажимает на другой профиль, который фрагменты складываются в память, быстро вызывая страшный OutOfMemoryError
. Вот диаграмма, описывающая то, что я описываю:
Пользователь нажимает на профиль Боба. Профиль пользователя Bob's UserA нажимает на ImageA, беря его в галерею фотографий различных пользователей (включая Боба). UserA щелкает по профилю Си затем на одном из ее образов - процесс повторяется, и т.д., и т.д.
UserA -> ViewProfileFragment
StoryViewFragment -> ViewProfileFragment
StoryViewFragment -> ViewProfileFragment
Так как вы можете видеть из обычного потока есть много примеров ViewProfileFragment
и StoryViewFragment
накапливался в backstack ,
Применимое КОД
Я загрузки их в виде фрагментов со следующей логикой:
//from MainActivity
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.activity_main_content_fragment, fragment, title);
ft.addToBackStack(title);
, что я попытался
1) Я специально с помощью FragmentTransaction
replace
так что метод будет запущен, когда принимает replace
место. Внутри Я пытаюсь высвободить столько ресурсов, сколько могу (например, очистка данных в адаптерах ListView
, «обнуление» переменных и т. Д.), Так что, когда фрагмент не является активным фрагментом и нажимается на заднюю часть, будет освобождается память. Но мои усилия по освобождению ресурсов - это лишь частичный успех. Согласно MAT, у меня все еще много памяти, которая потребляется GalleryFragment
и ViewProfileFragment
.
2) Я также удалил вызов addToBackStack(), но, очевидно, это плохой пользовательский интерфейс, потому что он не может вернуться назад (приложение просто закрывается, когда пользователь нажимает кнопку «Назад»).
3) Я использовал MAT для поиска всех объектов, которые занимают много места, и я использовал их разными способами в методах (и onResume
), чтобы высвободить ресурсы, но они все еще значительны в размере.
4) Я также написал цикл в оба фрагмента , который устанавливает все мои ImageViews
к нулю, используя следующую логику:
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 (фрагмент) не съедал все o В моей памяти?
2) Каковы «лучшие практики», когда ожидается, что много фрагментов можно загрузить в заднюю часть? Как разработчик правильно справляется с этим сценарием? (Или логика в моем заявлении по своей сути ошибочна, и я просто делаю это неправильно?)
Любая помощь в мозговом штурме решения этого будет очень признательна.
Вы используете метод onPause фрагмента? Http: //developer.android.com/reference/android/app/Fragment.html#onPause() Я думаю, вы должны освободить любые ресурсы растрового изображения, связанные с фрагментом в onPause метод фрагмента. И для повышения скорости, особенно если ваши изображения загружаются из Интернета, реализуйте кеш изображения. Вы можете использовать [Универсальный загрузчик изображений] (https://github.com/nostra13/Android-Universal-Image-Loader) или реализовать свой собственный. –
Да ' .onPause()' попадает, когда выдается '.replace (new_fragment)'. Я не думаю, что это мои проблемы, поскольку я вызываю 'listAdapter.clear()' в методе 'onPause()', удаляя любые данные изображения. Они загружаются с использованием Pico. –
AFAIK, 'listAdapter.clear()' не освобождает ресурсы растрового изображения, связанные со всем фрагментом ... По крайней мере, все они. Он удаляет только все элементы из списка. –