Android开发点点滴滴——软引用缓存图片和异步加载

1.软引用
Java中的SoftReference即对象的软引用。如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。使用软引用能防止内存泄露,增强程序的健壮性。   
SoftReference的特点是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。另外,一旦垃圾线程回收该Java对象之后,get()方法将返回null。
public HashMap<String,SoftReference<Bitmap>> imageCache=new HashMap<String,SoftReference<Bitmap>>();
[java] view plain copy
 
  1. SoftReference<Bitmap> bmpr=getBitmap(resStr);//从hashmap中通过resStr得到软引用  
  2. if(bmpr!=null)  
  3.         {  
  4.             if(bmpr.get()!=null)  
  5.             {  
  6.                 return bmpr.get();  
  7.             }  
  8.             else  
  9.             {  
  10.                 bmpr=readBitmapSoftReference(res);//如果内存被回收,bmpr get得到的null,此时,重新得到bitmap的软引用 new SoftReference<Bitmap>(bitmap);   
  11.                 if(bmpr!=null)  
  12.                 {  
  13.                     addBitmap(resStr,bmpr);//添加到hashmap中  
  14.                     return bmpr.get();  
  15.                 }  
  16.             }  
  17.         }  
  18.         else  
  19.         {  
  20.             //应先remove hashmap中的值   
  21.             bmpr=readBitmapSoftReference(res);  
  22.             if(bmpr!=null)  
  23.             {  
  24.                 addBitmap(resStr,bmpr);  
  25.                 return bmpr.get();  
  26.             }  
  27.               
  28.         }  
2.图片异步加载
这个问题涉及到线程 软引用等
首先当一个程序要显示网络图片时,下载的过程应该是在另外的线程中,那么就需要在其他线程中通知主线程来改变图片的view
其次,为了速度更快网络资源消耗小,使用缓存图片的方式,当第一次下载后,将图片存在本地,以后再查看时不用在网上重新下载
最后,为了防止内存泄露,使用软引用
图片异步加载类,如下
[java] view plain copy
 
  1. public class AsyncImageLoader {  
  2.       
  3.     public HashMap<String,SoftReference<Bitmap>> imageCache=null;     
  4.     public AsyncImageLoader()   
  5.     {  
  6.      imageCache = new HashMap<String,SoftReference<Bitmap>>();  
  7.     }  
  8.     //先查看缓存中,然后看sd卡  
  9.     public Bitmap loadBitmap(final ImageView imageView, final String imageURL,final String localImgFullName,   
  10.     final ImageCallBack imageCallBack)      
  11.     {      
  12.         //在内存缓存中,则返回Bitmap对象      
  13.         if(imageCache.containsKey(imageURL))      
  14.         {      
  15.             SoftReference<Bitmap> reference = imageCache.get(imageURL);      
  16.             Bitmap bitmap = reference.get();      
  17.             if(bitmap != null)      
  18.             {      
  19.                 return bitmap;      
  20.             }      
  21.         }      
  22.         else      
  23.         {     
  24.         File fis = new File(localImgFullName);  
  25.             if(!fis.exists())  
  26.                 return null;  
  27.           
  28.             return new SoftReference<Bitmap>(BitmapFactory.decodeFile(localImgFullName);  
  29.   
  30.       
  31.         }      
  32.               
  33.         final Handler handler = new Handler()      
  34.         {      
  35.           
  36.             @Override      
  37.             public void handleMessage(Message msg)      
  38.             {      
  39.                 // TODO Auto-generated method stub      
  40.                 imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);      
  41.             }      
  42.         };      
  43.               
  44.         //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片      
  45.         new Thread()      
  46.         {      
  47.            
  48.             @Override      
  49.             public void run()      
  50.             {      
  51.                 // TODO Auto-generated method stub     
  52.         URL myUrl;  
  53.         InputStream i = null;  
  54.         Bitmap bitmap=null;  
  55.         try{  
  56.                 myUrl = new URL(url);  
  57.                 if(myUrl==null)  
  58.                     return null;  
  59.             
  60.                 URLConnection myconn=myUrl.openConnection();  
  61.                 i=myconn.getInputStream();  
  62.             bitmap =BitmapFactory.decodeStream(i);  
  63.                  
  64.                 i.close();  
  65.                   
  66.                 if(bmp==null)  
  67.                     return null;  
  68.            }  
  69.         catch(Exception e)  
  70.             {  
  71.                   
  72.                 e.printStackTrace();  
  73.                 return null;  
  74.             }  
  75.                  
  76.                 imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));      
  77.                 Message msg = handler.obtainMessage(0, bitmap);      
  78.                 handler.sendMessage(msg);      
  79.                  
  80.                 File bitmapFile = new File(localImgFullName);      
  81.                 if(!bitmapFile.exists())      
  82.                 {      
  83.                     try      
  84.                     {      
  85.                         bitmapFile.createNewFile();      
  86.                     }      
  87.                     catch (IOException e)      
  88.                     {      
  89.                         // TODO Auto-generated catch block      
  90.                         e.printStackTrace();      
  91.                     }      
  92.                 }      
  93.                 FileOutputStream fos;      
  94.                 try      
  95.                 {      
  96.                     fos = new FileOutputStream(bitmapFile);      
  97.                     bitmap.compress(Bitmap.CompressFormat.PNG,       
  98.                             100, fos);      
  99.                     fos.close();      
  100.                 }      
  101.                 catch (FileNotFoundException e)      
  102.                 {      
  103.                     // TODO Auto-generated catch block      
  104.                     e.printStackTrace();      
  105.                 }      
  106.                 catch (IOException e)      
  107.                 {      
  108.                     // TODO Auto-generated catch block      
  109.                     e.printStackTrace();      
  110.                 }      
  111.             }      
  112.         }.start();      
  113.               
  114.         return null;      
  115.     }      
  116.     
  117.     public interface ImageCallBack      
  118.     {      
  119.         public void imageLoad(ImageView imageView, Bitmap bitmap);      
  120.     }      
  121. }    
  122. }     


注意的是在使用的时候,要实现imageCallBack借口
比如在某个地方要使用异步加载图片
[java] view plain copy
 
  1. AsyncImageLoader asyncBitmapLoader=new AsyncBitmapLoader();    
  2. Bitmap bitmap=asyncBitmapLoader.loadBitmap(image, imageURL,imgPath, new ImageCallBack() {    
  3.                     
  4.                 @Override    
  5.                 public void imageLoad(ImageView imageView, Bitmap bitmap) {    
  6.                     // TODO Auto-generated method stub    
  7.                     imageView.setImageBitmap(bitmap);    
  8.                 }    
  9.             });    
posted @ 2016-10-02 10:09  天涯海角路  阅读(100)  评论(0)    收藏  举报