博客
关于我
viewpage listview gridview加载本地大图多图OOM处理办法
阅读量:796 次
发布时间:2023-02-24

本文共 3874 字,大约阅读时间需要 12 分钟。

最近很少在博客园写东西了,但最近在公司项目中遇到了一个需要解决的问题。项目需要通过ViewPager方式加载本地相册,然而直接进入界面就会导致OOM(内存溢出)错误。经过几天的调试和优化,最终解决了这个问题,现在想和大家分享一下相关经验。

在解决这个问题的过程中,我提出了一个使用LruCache作为图片缓存工具类的方案。这个工具类能够有效地管理本地和网络图片的加载缓存。以下是这个工具类的代码实现和使用方法。

这个工具类的主要功能包括:

  • 对图片进行内存缓存,避免重复下载
  • 异步加载图片,减少主线程阻塞
  • 提供默认图片显示,直到图片加载完成
  • 支持本地图片和网络图片的加载
  • 使用这个工具类前,需要调用其暴露出的方法,并传入图片路径和ImageView控件。代码如下:

    package cn.haodehaode.utils;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.support.v4.util.LruCache;
    import android.widget.ImageView;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.HashSet;
    import java.util.Set;
    import cn.haodehaode.R;
    public class LruCacheImgUtils {
    private static LruCache
    mMemoryCache;
    private static LruCacheImgUtils lruCacheSingleton;
    public static synchronized LruCacheImgUtils getLruCacheSingleton() {
    if (lruCacheSingleton == null) {
    lruCacheSingleton = new LruCacheImgUtils();
    int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    int cacheSize = maxMemory / 8;
    mMemoryCache = new LruCache
    (cacheSize) {
    @Override
    protected int sizeOf(String key, Bitmap bitmap) {
    return bitmap.getByteCount() / 1024;
    }
    };
    }
    return lruCacheSingleton;
    }
    public void addBitmapToMemCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
    mMemoryCache.put(key, bitmap);
    }
    }
    public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
    }
    public void loadBitmap(String path, ImageView imageView) {
    final Bitmap bitmap = getBitmapFromMemCache(path);
    if (bitmap != null) {
    imageView.setImageBitmap(bitmap);
    } else {
    imageView.setImageResource(R.drawable.default_image);
    BitmapWorkerTask task = new BitmapWorkerTask(imageView);
    task.execute(path);
    }
    }
    public Bitmap decodeSampledBitmapFromResource(String path, int reqWidth, int reqHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(path, options);
    }
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
    final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
    }
    class BitmapWorkerTask extends AsyncTask
    {
    private ImageView mImageView;
    public BitmapWorkerTask(ImageView imageView) {
    mImageView = imageView;
    }
    @Override
    protected Bitmap doInBackground(String... params) {
    final Bitmap bitmap = decodeSampledBitmapFromResource(params[0], 320, 320);
    addBitmapToMemCache(params[0], bitmap);
    return bitmap;
    }
    @Override
    protected void onPostExecute(Bitmap bitmap) {
    super.onPostExecute(bitmap);
    mImageView.setImageBitmap(bitmap);
    }
    }
    }

    这个工具类的使用方法非常简单,只需调用setImageView方法,传入图片路径和ImageView控件即可。工具类会自动处理图片的缓存和加载,确保图片加载过程更加高效。

    代码如有问题,请随时反馈或联系我(QQ:30338970)。如果需要进一步了解图片加载优化的相关技术,也可以参考相关的技术文档或博客文章。

    转载地址:http://sspfk.baihongyu.com/

    你可能感兴趣的文章