图片的三级缓存

对图片进行缓存,刚开始的做法是实现三级缓存:

  内存缓存,优先加载,速度最快
  本地缓存,次优先加载,速度块
  网络缓存,不优先加载,速度慢,浪费流量

网络缓存是直接通过向服务器请求,获取图片

本地缓存是将从网络请求后得到的图片保存至本地sdcard中

本地缓存是将从网络请求后得到的图片保存至内存中


但是手机的内存是有限的,而且给每个应用分配的内存也是很小的,所以容易造成内存溢出(OOM);

解决此办法是使用弱引用,因为弱引用在内存不够时,垃圾回收机制会将其回收,才会保持足够的空间。

弱引用:SoftReference:

 HashMap<String,SoftReference<Bitmap>>hashMap=new HashMap<>();

但是在Android2.3+,这种弱引用很容易就被回收,所以达不到原有的效果

解决办法是使用:LruCache;

 将内存控制在一定大小内,超出最大值会自动回收,这个最大值开发者自己定

LruCache memoryCache=new LruCache<String, Bitmap>((int) maxSize){
    @Override
    protected int sizeOf(String  key, Bitmap value) {
        int byteCount=value.getRowBytes()*value.getHeight();//图片的大小
        return byteCount;
    }
};

对图片的压缩

 //进行图片的压缩
 BitmapFactory.Options option=new BitmapFactory.Options();
 option.inSampleSize=2;//压缩至原图片的1/2
 option.inPreferredConfig= Bitmap.Config.RGB_565;//设置图片的格式

Bitmap bitmap= BitmapFactory.decodeStream(is,null,option);

最后贴上代码:

网络缓存:

public class NetChache {

    private ImageView ivPic;
    private String url;

    private LocalCacheUtil localCache;
    private MemoryCacheUtil memoryCache;

    public NetChache(LocalCacheUtil localCache,MemoryCacheUtil memoryCache){
        this.localCache=localCache;
        this.memoryCache=memoryCache;
    }
    /*
    * 从网络下载图片
    * */
    public Bitmap getBitmapFromNet(ImageView ivPic, String url) {
        new BitmapTask().execute(ivPic, url);
        return null;
    }

    /*
    * Handler与线程池的封装
    * */
    class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

        /*
        * 后台执行耗时操作
        * 子线程
        * */
        @Override
        protected Bitmap doInBackground(Object... params) {
            ivPic = (ImageView) params[0];
            url = (String) params[1];
//           ivPic.setTag(url);
            return  downloadBitmap(url);
        }

        /*
        * 更新进度
        * 主线程
        * */
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        /*
        * 耗时方法执行完毕,执行此方法
        * */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap!=null){
                ivPic.setImageBitmap(bitmap);
                //缓存至本地
                localCache.setBitmapToLocal(url,bitmap);
                memoryCache.setBitmapToMemory(url,bitmap);
            }

        }
    }

    private Bitmap downloadBitmap(String url) {
        HttpURLConnection connection=null;
        try {
            URL  u = new URL(url);
            connection= (HttpURLConnection) u.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            if (connection.getResponseCode()==200){
                InputStream is=connection.getInputStream();
                //进行图片的压缩
                BitmapFactory.Options option=new BitmapFactory.Options();
                option.inSampleSize=2;//压缩至原图片的1/2
                option.inPreferredConfig= Bitmap.Config.RGB_565;//设置图片的格式

               Bitmap bitmap= BitmapFactory.decodeStream(is,null,option);
                return bitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            connection.disconnect();
        }
        return null;
    }

}

本地缓存:

public class LocalCacheUtil {
    public static final String CACHE_PATH= Environment.
            getExternalStorageDirectory()+
            "/sendizhihui_cache";
    /*
    * 从本地sdcard读取图片
    * */
    public Bitmap getBitmapFromLocal(String url){
        try {
            String fileName=MD5Encoder.encode(url);
            File file=new File(CACHE_PATH,fileName);
            if (file.exists()){
              Bitmap bitmap=  BitmapFactory.decodeStream(new FileInputStream(file));
                return bitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /*
    * 向sdcard写图片
    * */
    public void setBitmapToLocal(String url, Bitmap bitmap){
        try {
            String fileName=MD5Encoder.encode(url);
            File file=new File(CACHE_PATH,fileName);
            File parentFile=file.getParentFile();
            if (!parentFile.exists()) {//如果文件夹不存在,则创建文件夹
                parentFile.mkdirs();
            }
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,
                            new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
内存缓存:

public class MemoryCacheUtil {
//    HashMap<String,SoftReference<Bitmap>>hashMap=new HashMap<>();
    private LruCache<String,Bitmap>memoryCache;
    public MemoryCacheUtil(){
        long maxSize=Runtime.getRuntime().maxMemory()/8;//模拟器默认为16m
        memoryCache=new LruCache<String, Bitmap>((int) maxSize){
            @Override
            protected int sizeOf(String  key, Bitmap value) {
                int byteCount=value.getRowBytes()*value.getHeight();//图片的大小
                return byteCount;
            }
        };
    }
    /*
    * 从内存读取
    * */
    public Bitmap getBitmapFromMemory(String url){
//        //弱引用
//        SoftReference<Bitmap>softReference=hashMap.get(url);
//        if (softReference!=null){
//            Bitmap bitmap=softReference.get();
//            return bitmap;
//        }
        return memoryCache.get(url);
    }

    /*
    * 将图片写进内存
    * */
    public void setBitmapToMemory(String url,Bitmap bitmap){
//        SoftReference<Bitmap>softReference=new SoftReference<Bitmap>(bitmap);
//        hashMap.put(url,softReference);
        memoryCache.put(url,bitmap);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值