[英]How to release memory of bitmap using imageloader in android?
我正在從服務器將圖像加載到網格視圖中。 為此,我正在使用通用圖像加載器。 我在適配器的getview()方法中使用圖像加載器。 它從arraylist獲取圖像的URL並從服務器加載圖像。 圖像可以是100年代。 我正在片段中顯示網格視圖,因此對於每個片段,都有一個單獨的網格視圖。 當我長時間在多個片段之間切換時,我不再出現內存不足錯誤。
建議的解決方案 :
所以我使用第三方庫加載圖像。 我只是在調用函數中傳遞圖像視圖,那么如何釋放位圖?
我猜堆內存是動態的,每當內存增加時,垃圾收集器就會釋放內存。
3.使用UIL / Picasso / Glide以避免內存泄漏
4.Code釋放片段onDestroy()方法的內存()
private void unbindDrawables(View view)
{
if (view.getBackground() != null)
{
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView))
{
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
{
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
我已經在使用第三方庫了。
這是我的gridViewAdapter類的代碼。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View view = convertView;
if (view == null)
{
view = inflater.inflate(R.layout.grid_item_photo, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) view.findViewById(R.id.imgLoader);
holder.play = (ImageView) view.findViewById(R.id.play);
view.setTag(holder);
}
else
{
holder = (ViewHolder) view.getTag();
}
try{
if(IMAGES_LIST.get(position).getType().equals("video"))
{
holder.play.setVisibility(View.VISIBLE);
}
else
{
holder.play.setVisibility(View.GONE);
}
ImageLoader.getInstance().displayImage(AppConst.BASE_IMAGE_URL+IMAGES_LIST.get(position).getThumbnail(), holder.imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
view.setClickable(true);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
view.setClickable(true);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
view.setClickable(false);
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
}
});
}catch(Exception e)
{
}
catch(OutOfMemoryError e)
{
}
return view;
}
static class ViewHolder {
ImageView imageView,play;
}
}
這聽起來像你的片段泄漏 - 即使調用了onDestroy,你的片段也會在所有內容(包括位圖)中保留在內存中。 您可以使用MAT + Heap轉儲查看確切導致泄漏的原因(那里有許多指南)。 第一個嫌疑人應該是片段類中的單例,你可以從你的片段傳遞“this”。 作為第一步,我將從onDestroy中的片段中清除所有內容。
使“SimpleImageLoadingListener()”成為一個內部靜態類,將您的片段保存為WeakReference - 這可能會減少泄漏(或至少其中一個)。
您應該將任何第三個ImageLoader用作具有一個LRU緩存+一個磁盤緩存的Singleton。 你可以在這里找到一些好的( 任何最好的第三方工具來緩存Android中的圖像? )
清單中的“largeHeap”根本不應該出現在你的腦海里。 一旦你有泄漏,那么你將只有一個更大的堆來填補,直到OOM。
Yo可以刪除內存緩存中的緩存圖像。 使用MemoryCacheUtil
:
MemoryCacheUtils.removeFromCache(imageUrl, imageLoader.getMemoryCache());
和DiscCacheUtils
一起刪除discCache
DiscCacheUtils.removeFromCache(url, ImageLoader.getInstance().getDiscCache());
此外,您可以使用以下方法清除內存緩存
imageLoader.clearMemoryCache();
此外,您可以使用限制來控制內存和磁盤:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
.discCache(new UnlimitedDiscCache(cacheDir))
可能是因為你只是通過創建它的實例來使用ImageLoader
以及我不知道你有什么DisplayImageOptions
嘗試更改選項設置並檢查它。對我來說這個選項可以幫助我加載大圖像List
。
在您的應用中嘗試此選項。
DisplayImageOptions imageOptions = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.ic_launcher).showImageOnFail(R.drawable.ic_launcher).resetViewBeforeLoading(true).cacheOnDisk(true).imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true).displayer(new FadeInBitmapDisplayer(3000, true, true, false)).build();
您可以嘗試避免內存緩存,並限制磁盤緩存。 如需進一步優化,您可以查看來源 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.