android中實現图片的三级缓存

在我们的app中,有些图片可能会反复使用到,如果每次使用都从网络加载的话既浪费流量又浪费资源,so图片的三级缓存必须实现,实现的步骤思路如下:
  • 缓存在内存中使用LruCashe是最好的了,不需要什么弱引用强引用,LruCache满足先进先出的原则,当我们为图片缓存分配的内存不够时他会将使用最少的或者最先存入的图片删除
  • 缓存到磁盘中使用原生的IO即可
  • 从网络加载使用IO(可根据实际情况选择)
新建ImageHelper类如下,
public class ImageHelper {    
//内存缓存池    
private static LruCache<String,Bitmap> mCache;
/开辟子线程执行任务  
  private static Handler mHandler;
//线程管理者   
 private static ExecutorService mThreadPoor;    
private static Map<ImageView,Future<?>> mTaskTags = new    LinkedHashMap ImageView,Future<?>>();  
  private Context mContext;  
 public ImageHelper(Context context){   
     this.mContext = context;       
 if(mCache==null){            
//最大使用的内存空间 为剩余内存的四分之一      
  int maxSize = (int)(Runtime.getRuntime().freeMemory()/4);       
     mCache = new LruCache<String, Bitmap>(maxSize){         
       @Override               
 protected int sizeOf(String key, Bitmap value) {          
          return value.getRowBytes()*value.getHeight();   
             }        
    };           
 if(mHandler==null){       
         mHandler = new Handler() ;  
          }          
  if(mThreadPoor==null){       
         //最多同时允许的线程数为三个          
      mThreadPoor = Executors.newFixedThreadPool(3);  
          }   
     }    
}    
public void display(ImageView iv,String url){  
      //1.去内存中取    
    Bitmap bitmap = mCache.get(url);       
 if(bitmap!=null){         
   iv.setImageBitmap(bitmap); 
           return;     
   }       
 //2.去硬盘上取      
  try {          
  bitmap = loadBitmapFromLocal(url);    
    } catch (Exception e) {  
          e.printStackTrace();   
     }      
  if(bitmap!=null){     
       iv.setImageBitmap(bitmap);   
         return;     
   }      
  //3.从网络获取图片    
    loadBitMapFromNet(iv,url);  
  }   
 private void loadBitMapFromNet(ImageView iv,String url){ 
       Future<?> future = mTaskTags.get(iv);   
     if(future!=null&&!future.isCancelled()&&!future.isDone()){     
       Log.i("正在加载","取消当前任务");        
    future.cancel(true);        
    future=null;     
   }       
 future = mThreadPoor.submit( new ImageLoadTask(iv,url)); 
       mTaskTags.put(iv,future);    
    Log.i("标记任务","");  
  }   
 class ImageLoadTask implements Runnable{      
  private ImageView iv;       
 private String url;       
 public ImageLoadTask(ImageView iv,String url){    
         this.iv = iv;       
      this.url = url;      
  }      
  @Override    
    public void run() {     
       try {           
     HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();   
             conn.setConnectTimeout(3*1000);        
          	conn.setReadTimeout(30*1000);  
              conn.connect();               
 int code = conn.getResponseCode();          
      if(code==200){                  
  InputStream is = conn.getInputStream();      
               Bitmap bitmap = BitmapFactory.decodeStream(is);
//	存入内存池                    
	mCache.put(url,bitmap);        
            try {
//写入硬盘               
         writeToLocal(url,bitmap );    
                } catch (Exception e) {  
                      e.printStackTrace();           
         }                 
   mHandler.post(new Runnable() {     
                   @Override       
                 public void run() {
//加载图片                              
    display(iv,url);            
            }               
     });          
      }       
     } catch (IOException e) {   
             e.printStackTrace();      
      }      
   }
//从硬盘中获取图片   
 private Bitmap loadBitmapFromLocal(String url) throws Exception {  
      String name;      
  name = MD5Encoder.encode(url);     
   File file = new File(getCacheDir(),name);
        if(file.exists()){         
   Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());   
         mCache.put(url,bitmap);  
          return bitmap;    
    }       
 return null;   
 }   
 private void writeToLocal(String url,Bitmap bitmap) throws Exception {     
   String name;    
    FileOutputStream fos = null;    
    name = MD5Encoder.encode(url);  
      File file = new File(getCacheDir(),name);     
   fos = new FileOutputStream(file);    
  bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);   
     if(fos!=null){       
     fos.close();       
     fos=null;      
  }   
 }   
 private String getCacheDir(){     
   String state = Environment.getExternalStorageState();   
     File dir = null;     
   if(Environment.MEDIA_MOUNTED.equals(state)){  
          //有sd卡      
  dir = new 
File(Environment.getExternalStorageDirectory(),"/Android/data/"+mContext.getPackageName()+"/Icon");   
     }else{         
   dir = new File(mContext.getCacheDir(),"/Icon");     
   }      
  if(!dir.exists()){           
 dir.mkdirs();        }      
  return  dir.getAbsolutePath();    }}



附带 MD5Encoder帮助类:
public class MD5Encoder {   
 public static String encode(String string) throws Exception {  
      byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));  
      StringBuilder hex = new StringBuilder(hash.length * 2);  
      for (byte b : hash) {     
       if ((b & 0xFF) < 0x10) {        
        hex.append("0");        
    }           
 hex.append(Integer.toHexString(b & 0xFF));  
      }        
return hex.toString();   
 }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值