У меня есть несколько видов деятельности, где я показываю изображения с помощью этой библиотеки. Дело в том, что в приложении заканчивается память. Я попытался gc.clean(), нулевые ссылки, вызывать clear на объекте imageloader, но напрасно.
В MAT я обнаружил, что у меня есть несколько объектов одного и того же действия, и это поведение по умолчанию, если я не ошибаюсь. Я использовал singleInstance для подавления нескольких экземпляров, и это помогло с утечками памяти.
Прямо сейчас, из-за singleInstance, у меня проблемы с навигацией. Как вы думаете, я должен продолжить работу с singleInstance или попытаться исправить утечку памяти несколькими экземплярами?
Здесь ImageView gc корни инспекции:
UPD:
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
ImageView imageView = (ImageView) convertView;
if(convertView == null){
imageView = new ImageView(_currentActivity);
}
UPD2 (стратегии навигации):
У меня есть постоянный заголовок с кнопками, которые запускают домашнюю активность (с галереей) и активность профиля; во-вторых, есть подзаголовок, в котором также есть 3 кнопки, которые указывают на другие 3 действия со списками (состоящие из изображений + метки).
Эти элементы заголовка, подзаголовка доступны для каждого действия в приложении; Кнопки-ссылки ничего не делают:
startActivity(new Intent(getActivity(), MainActivity.class));
или
Intent activityIntent = new Intent(getActivity(), SomeActivityWithListViewInside.class);
// passing some data like list id
activityIntent.putExtra("list_id", listId);
startActivity(activityIntent);
Таким образом, эти экземпляры активности вызваны вызовами startActivity - как вы думаете, я должен играть с singleTop или любым другим параметром намерения, чтобы избежать этой проблемы?
Вы не должны использовать singleInstance launchMode. Вам нужно, чтобы ваша навигация работала правильно, используя стандартный и/или singleTop launchMode. Если вы обнаружите, что у вас есть несколько экземпляров вашей активности, но вы этого не ожидали, значит, у вас что-то не так в вашей навигации. Наличие нескольких экземпляров ваших действий поддерживает все ваши взгляды и изображения вокруг и, вероятно, то, что вызывает проблемы с памятью.
Обновите свой пост с ожидаемой навигацией и тем, как вы управляете им, и, возможно, мы сможем помочь вам исправить это.
РЕДАКТИРОВАТЬ: ответить на постер UPD:
Я не знаю, где вы устанавливаете _currentActivity
, но это может быть вашей проблемой. Когда вы создаете представление внутри адаптера, вы всегда должны использовать контекст адаптера (который настроен, когда он был создан). Поэтому попробуйте следующее:
ImageView imageView = (ImageView) convertView;
if(convertView == null){
imageView = new ImageView(getContext());
}
EDIT: ответьте на плакат UPD2:
Вам необходимо проверить свою навигацию, чтобы убедиться, что, когда пользователь выбирает одну из кнопок в заголовке или подзаголовке, у вас нет нескольких экземпляров ваших действий в стеке действий (если это не то, что вы хотите). Если в ваших действиях используется много пространства изображений (растровые изображения и т.д.), Вы должны убедиться, что у вас нет нескольких экземпляров. Вы можете переосмыслить свою навигацию или использовать комбинации singleTop, clearTop, reorderToFront и т.д., Чтобы не создавать экземпляры ваших действий, а просто переупорядочивать их в стеке действий, чтобы получить желаемое поведение навигации.
я бы настоятельно рекомендовал не использовать странные флаги действий. У меня также всегда были проблемы с навигацией (и все еще есть, даже с фрагментами) с использованием API android.
вместо этого я предлагаю решить проблемы с памятью.
вы должны посмотреть это видео о утечках памяти и прочитать это о растровых изображениях.
Короче говоря, вот несколько советов:
старайтесь избегать статических ссылок, особенно если они ссылаются на контекст.
старайтесь избегать ссылок на контекст.
если вы должны ссылаться на контекст, подумайте об использовании ApplicationContext.
не забудьте закрыть потоки и диалоги при закрытии операции (при необходимости). попытайтесь закрыть службы, когда они больше не нужны.
предпочитают статические внутренние классы над не статическими внутренними классами (поскольку они ссылаются на содержащийся класс).
помните, что анонимные классы также имеют ссылку на содержащий класс.
будьте осторожны с тем, что вы кешируете. старайтесь избегать кэширования классов, содержащих ссылку на контекст, например, виды и чертежи.
если возможно, попробуйте использовать softReference и/или weakReference для ссылки на "опасные" объекты, ссылающиеся на контекст.
на API android API 10 и ниже, не забудьте переработать ваши растровые изображения. они обычно занимают много памяти.
если действие занимает слишком много памяти, и вы переходите от него к другому действию, подумайте о его завершении и повторном создании, когда это необходимо, вместо того, чтобы возвращаться к его старому экземпляру.
если вы используете какие-либо сторонние библиотеки или используете собственный код (например, с помощью NDK), не забудьте освободить его, когда это не понадобится. Далвик не поможет вам в этом.
Передача активности как контекста при создании представления не является хорошей: это предотвращает "освобождение" активности. Также вам может понадобиться масштабировать растровые изображения до требуемого размера.