zoukankan      html  css  js  c++  java
  • 图片的三级缓存

    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<String, Bitmap> firstCacheIma = new LinkedHashMap<String, Bitmap>(MAX_CAPACTITY, 0.75f, true){
            //根据返回值移除map中最老的值
            protected boolean removeEldestEntry(java.util.Map.Entry<String,Bitmap> eldest) {
                if(this.size() > MAX_CAPACTITY){
                    
                    //加入二级缓存  软引用 在内存不足,回收
                    secondCache.put(eldest.getKey(), new SoftReference<Bitmap>(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<String, SoftReference<Bitmap>>  secondCache = 
                new ConcurrentHashMap<String, SoftReference<Bitmap>>();    
        
        //三级缓存;本地缓存 写入内部存储
        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<String, Void , Bitmap>{
    
            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<Bitmap> 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();
        }
    }
  • 相关阅读:
    魅族Java面经
    笔试常考的Java基础
    笔试常考的Linux命令大全
    Spring概念
    Java三大框架的配置
    Myeclipse的使用
    项目经验
    Android四大组件及activity的四大启动模式
    java基础
    IT在线笔试总结(二)
  • 原文地址:https://www.cnblogs.com/wei1228565493/p/4676924.html
Copyright © 2011-2022 走看看