Andriod 图片缓存

转载至:Android ListView从网络获取图片及文字显示 http://blog.csdn.net/wangjinyu501/article/details/8219317

1、内存缓存;软引用:如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存

public class MemoryCache {  
    private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());//软引用  
      
    public Bitmap get(String id){  
        if(!cache.containsKey(id))  
            return null;  
        SoftReference<Bitmap> ref=cache.get(id);  
        return ref.get();  
    }  
      
    public void put(String id, Bitmap bitmap){  
        cache.put(id, new SoftReference<Bitmap>(bitmap));  
    }  
  
    public void clear() {  
        cache.clear();  
    }  
}  

2、文件缓存;

public class FileCache {  
      
    private File cacheDir;  
      
    public FileCache(Context context){  
        //找一个用来缓存图片的路径  
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))  
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");  
        else  
            cacheDir=context.getCacheDir();  
        if(!cacheDir.exists())  
            cacheDir.mkdirs();  
    }  
      
    public File getFile(String url){       
        String filename=String.valueOf(url.hashCode());  
        File f = new File(cacheDir, filename);  
        return f;          
    }  
      
    public void clear(){  
        File[] files=cacheDir.listFiles();  
        if(files==null)  
            return;  
        for(File f:files)  
            f.delete();  
    }   
}  

3、图片管理类

public class ImageLoader {   
    
    MemoryCache memoryCache=new MemoryCache();   
    FileCache fileCache;   
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());   
    ExecutorService executorService;    
    
    public ImageLoader(Context context){   
        fileCache=new FileCache(context);   
        executorService=Executors.newFixedThreadPool(5);   
    }   
    
    final int stub_id = R.drawable.no_image;   
    public void DisplayImage(String url, ImageView imageView)   
    {   
        imageViews.put(imageView, url);   
        Bitmap bitmap=memoryCache.get(url);   
        if(bitmap!=null)   
            imageView.setImageBitmap(bitmap);   
        else  
        {   
            queuePhoto(url, imageView);   
            imageView.setImageResource(stub_id);   
        }   
    }   
    
    private void queuePhoto(String url, ImageView imageView)   
    {   
        PhotoToLoad p=new PhotoToLoad(url, imageView);   
        executorService.submit(new PhotosLoader(p));   
    }   
    
    private Bitmap getBitmap(String url)   
    {   
        File f=fileCache.getFile(url);   
    
        //从sd卡  
        Bitmap b = decodeFile(f);   
        if(b!=null)   
            return b;   
    
        //从网络  
        try {   
            Bitmap bitmap=null;   
            URL imageUrl = new URL(url);   
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();   
            conn.setConnectTimeout(30000);   
            conn.setReadTimeout(30000);   
            conn.setInstanceFollowRedirects(true);   
            InputStream is=conn.getInputStream();   
            OutputStream os = new FileOutputStream(f);   
            Utils.CopyStream(is, os);   
            os.close();   
            bitmap = decodeFile(f);   
            return bitmap;   
        } catch (Exception ex){   
           ex.printStackTrace();   
           return null;   
        }   
    }   
    
    //解码图像用来减少内存消耗  
    private Bitmap decodeFile(File f){   
        try {   
            //解码图像大小  
            BitmapFactory.Options o = new BitmapFactory.Options();   
            o.inJustDecodeBounds = true;   
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);   
    
            //找到正确的刻度值,它应该是2的幂。  
            final int REQUIRED_SIZE=70;   
            int width_tmp=o.outWidth, height_tmp=o.outHeight;   
            int scale=1;   
            while(true){   
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)   
                    break;   
                width_tmp/=2;   
                height_tmp/=2;   
                scale*=2;   
            }   
    
            BitmapFactory.Options o2 = new BitmapFactory.Options();   
            o2.inSampleSize=scale;   
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);   
        } catch (FileNotFoundException e) {}   
        return null;   
    }   
    
    /任务队列  
    private class PhotoToLoad   
    {   
        public String url;   
        public ImageView imageView;   
        public PhotoToLoad(String u, ImageView i){   
            url=u;   
            imageView=i;   
        }   
    }   
    
    class PhotosLoader implements Runnable {   
        PhotoToLoad photoToLoad;   
        PhotosLoader(PhotoToLoad photoToLoad){   
            this.photoToLoad=photoToLoad;   
        }   
    
        @Override  
        public void run() {   
            if(imageViewReused(photoToLoad))   
                return;   
            Bitmap bmp=getBitmap(photoToLoad.url);   
            memoryCache.put(photoToLoad.url, bmp);   
            if(imageViewReused(photoToLoad))   
                return;   
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);   
            Activity a=(Activity)photoToLoad.imageView.getContext();   
            a.runOnUiThread(bd);   
        }   
    }   
    
    boolean imageViewReused(PhotoToLoad photoToLoad){   
        String tag=imageViews.get(photoToLoad.imageView);   
        if(tag==null || !tag.equals(photoToLoad.url))   
            return true;   
        return false;   
    }   
    
    //用于显示位图在UI线程  
    class BitmapDisplayer implements Runnable   
    {   
        Bitmap bitmap;   
        PhotoToLoad photoToLoad;   
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}   
        public void run()   
        {   
            if(imageViewReused(photoToLoad))   
                return;   
            if(bitmap!=null)   
                photoToLoad.imageView.setImageBitmap(bitmap);   
            else  
                photoToLoad.imageView.setImageResource(stub_id);   
        }   
    }   
    
    public void clearCache() {   
        memoryCache.clear();   
        fileCache.clear();   
    }   
}

  

  

posted @ 2016-02-18 23:37  chenyizh  阅读(135)  评论(0)    收藏  举报