博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图片的三级缓存
阅读量:7235 次
发布时间:2019-06-29

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

public class ImageLoader {        //一级缓存的最大数量    private static final int MAX_CAPACTITY = 20;    //下载图片时的默认图片    private DefaultImage image = new DefaultImage();    private Context mContext;        private  ImageLoader(Context context){        this.mContext = context;    }    private ImageLoader(){};        private static ImageLoader instance;    public static ImageLoader getInstance(Context context){        if(instance == null){            instance = new ImageLoader(context);        }        return instance;            }            //三级缓存    //一级缓存 强引用 在内存溢出时 也不回收    //20张        /**     * String bitmap的路径     * bitmap 图片     */    private LinkedHashMap
firstCacheIma = new LinkedHashMap
(MAX_CAPACTITY, 0.75f, true){ //根据返回值移除map中最老的值 protected boolean removeEldestEntry(java.util.Map.Entry
eldest) { if(this.size() > MAX_CAPACTITY){ //加入二级缓存 软引用 在内存不足,回收 secondCache.put(eldest.getKey(), new SoftReference
(eldest.getValue())); //加入三级缓存 本地缓存 diskCache(eldest.getKey(),eldest.getValue()); } return false; } }; /** * 本地缓存 * @param key 图片的路径 (会被当做名称保存到硬盘) * @param value */ private void diskCache(String key, Bitmap value) { String name = MD5utils.decode(key); String path = mContext.getCacheDir().getAbsolutePath()+ File.separator +name; FileOutputStream fos = null; try { fos = new FileOutputStream(path); //保存成JPG格式 value.compress(Bitmap.CompressFormat.JPEG, 100, fos); } catch (FileNotFoundException e) { e.printStackTrace(); }finally{ if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }; //二级缓存,超过20张 //线程安全 并发的 private static ConcurrentHashMap
> secondCache = new ConcurrentHashMap
>(); //三级缓存;本地缓存 写入内部存储 public void loadImage(String key,ImageView imageView){ //读取缓存 Bitmap bitmap = getFromCachr(key); if(bitmap != null){ cancelDownload(key, imageView); imageView.setImageBitmap(bitmap); }else{ //设置默认图片 imageView.setImageDrawable(image); //访问网络 AsynImagLoaderTask task = new AsynImagLoaderTask(imageView); task.execute(key); } } //异步下载图片 class AsynImagLoaderTask extends AsyncTask
{ private String key; private ImageView imageView; public AsynImagLoaderTask(ImageView imageView) { super(); this.imageView = imageView; } @Override protected Bitmap doInBackground(String... params) { key = params[0]; return downLoadImag(key); } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if(isCancelled()){ result =null; } if(result != null){ //添加到一级缓存 addFirstCache( key, result); //显示图片 imageView.setImageBitmap(result); } } } private void cancelDownload(String key,ImageView result){ //可能有多个任务下载同一张图片 AsynImagLoaderTask task = new AsynImagLoaderTask(result); if( task != null){ String downKey = task.key; if(downKey == null || !downKey.equals(key)){ //设置标识 task.cancel(true); } } } /** * 加入一级缓存 * @param key2 * @param result */ private void addFirstCache(String key2, Bitmap result) { if(result != null){ synchronized (firstCacheIma) { firstCacheIma.put(key2, result); } } } private Bitmap getFromCachr(String key) { //从一级缓存加载 synchronized (firstCacheIma) { Bitmap bitmap = firstCacheIma.get(key); //保持图片的新鲜 if(bitmap != null){ firstCacheIma.remove(bitmap); firstCacheIma.put(key, bitmap); return bitmap; } } //从二级缓存加载 SoftReference
softReference = secondCache.get(key); if(softReference != null){ Bitmap bitmap = softReference.get(); if(bitmap != null){ //添加到一级缓存 firstCacheIma.put(key, bitmap); return bitmap; } }else{ //软引用呗回收了,从缓存中清楚 secondCache.remove(key); } //从本地缓存加载 Bitmap load_bitmap = getFromLocal( key); if(load_bitmap != null){ //添加到一级缓存 firstCacheIma.put(key, load_bitmap); return load_bitmap; } return null; } /** * 从本地缓存中读取 * @param key * @return */ private Bitmap getFromLocal(String key) { String name = MD5utils.decode(key); if(name == null){ return null; } String path = mContext.getCacheDir().getAbsolutePath() + File.separator + name; FileInputStream fis = null; try { fis = new FileInputStream(path); return BitmapFactory.decodeStream(fis); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } /** * 下载图片 * @param key2 * @return */ private Bitmap downLoadImag(String key2) { InputStream is = null; try { is = DownImag.getImag(key2); return BitmapFactory.decodeStream(is); } catch (IOException e) { e.printStackTrace(); }finally{ if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 设置默认图片 * */ static class DefaultImage extends ColorDrawable{ public DefaultImage(){ super(Color.GRAY); } }}

Adapter中使用:

public class MyAdapter extends BaseAdapter{    private Context context;    private LayoutInflater inflater;    private ImageLoader loader;    private String[] str;    public MyAdapter (Context context,String[] str){        this.context = context;        inflater = LayoutInflater.from(context);        this.str= str;        loader = ImageLoader.getInstance(context);    }    @Override    public int getCount() {                return str.length;    }        @Override    public Object getItem(int position) {                return str[position];    }    @Override    public long getItemId(int position) {                return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if(convertView == null){             holder = new ViewHolder();            convertView = inflater.inflate(com.example.test.R.layout.list_item, null);            holder.imageView = (ImageView) convertView.findViewById(com.example.test.R.id.item);            convertView.setTag(holder);        }else{            holder = (ViewHolder) convertView.getTag();        }        loader.loadImage(str[position], holder.imageView);        return convertView;    }        class ViewHolder{        ImageView imageView;    }}

Md5Utils

public class MD5utils {        public static String decode(String key){        MessageDigest digest = null;        try {            digest = MessageDigest.getInstance("MD5");            digest.reset();            //UTF-8编码                            digest.update(key.getBytes("utf-8"));            } catch (UnsupportedEncodingException e) {                // TODO Auto-generated catch block                e.printStackTrace();                    } catch (NoSuchAlgorithmException e) {                        e.printStackTrace();        }                byte[] byteArray = digest.digest();        StringBuffer buffer = new StringBuffer();        for(int i = 0; i< byteArray.length;i++){                    }                return key;            }}

DownImage:

public class DownImag {        public static InputStream getImag(String key) throws IOException{        URL url = new URL(key);        HttpURLConnection connection = (HttpURLConnection) url.openConnection();        return connection.getInputStream();    }}

 

转载于:https://www.cnblogs.com/wei1228565493/p/4676924.html

你可能感兴趣的文章
多线程,silverlight_Rest_WCF,dynamic 索引帖
查看>>
设计并实现同时支持多种视频格式的流媒体点播系统
查看>>
Vmware下Mac系统Vmware tools安装
查看>>
mysql间隙锁next-key
查看>>
linux和windows文件名称长度限制
查看>>
开源项目之easyrtmp
查看>>
怎样打开64位 Ubuntu 的32位支持功能?
查看>>
360路由器c301最新固件支持万能中继
查看>>
RESTful API 设计最佳实践
查看>>
DTD中的属性类型
查看>>
git 服务器的搭建
查看>>
Redis学习笔记8--Redis发布/订阅
查看>>
C++ 类的动态组件化技术
查看>>
【JS小技巧】JavaScript 函数用作对象的隐藏问题(F.ui.name)
查看>>
《OpenGL编程指南第七版》学习——编译时提示“error C2381: “exit” : 重定义;__declspec(noreturn) 不同”错误的解决办法...
查看>>
SaltStack–Job管理
查看>>
firefox快捷键窗口和标签类
查看>>
SpringBoot配置ActiveMQ
查看>>
作用域重叠
查看>>
Java注解的简单了解
查看>>