[英]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.