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

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>>();
SoftReference<Bitmap> bmpr=getBitmap(resStr);//从hashmap中通过resStr得到软引用
if(bmpr!=null)
		{
			if(bmpr.get()!=null)
			{
				return bmpr.get();
			}
			else
			{
				bmpr=readBitmapSoftReference(res);//如果内存被回收,bmpr get得到的null,此时,重新得到bitmap的软引用 new SoftReference<Bitmap>(bitmap); 
				if(bmpr!=null)
				{
					addBitmap(resStr,bmpr);//添加到hashmap中
					return bmpr.get();
				}
			}
		}
		else
		{
			//应先remove hashmap中的值 
			bmpr=readBitmapSoftReference(res);
			if(bmpr!=null)
			{
				addBitmap(resStr,bmpr);
				return bmpr.get();
			}
			
		}
2.图片异步加载
这个问题涉及到线程 软引用等
首先当一个程序要显示网络图片时,下载的过程应该是在另外的线程中,那么就需要在其他线程中通知主线程来改变图片的view
其次,为了速度更快网络资源消耗小,使用缓存图片的方式,当第一次下载后,将图片存在本地,以后再查看时不用在网上重新下载
最后,为了防止内存泄露,使用软引用
图片异步加载类,如下
public class AsyncImageLoader {
    
	public HashMap<String,SoftReference<Bitmap>> imageCache=null;   
	public AsyncImageLoader() 
	{
	 imageCache = new HashMap<String,SoftReference<Bitmap>>();
	}
	//先查看缓存中,然后看sd卡
	public Bitmap loadBitmap(final ImageView imageView, final String imageURL,final String localImgFullName, 
	final ImageCallBack imageCallBack)    
	{    
        //在内存缓存中,则返回Bitmap对象    
        if(imageCache.containsKey(imageURL))    
        {    
            SoftReference<Bitmap> reference = imageCache.get(imageURL);    
            Bitmap bitmap = reference.get();    
            if(bitmap != null)    
            {    
                return bitmap;    
            }    
        }    
        else    
        {   
		File fis = new File(localImgFullName);
	       	if(!fis.exists())
	       		return null;
		
	       	return new SoftReference<Bitmap>(BitmapFactory.decodeFile(localImgFullName);

	
        }    
            
        final Handler handler = new Handler()    
        {    
        
            @Override    
            public void handleMessage(Message msg)    
            {    
                // TODO Auto-generated method stub    
                imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);    
            }    
        };    
            
        //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片    
        new Thread()    
        {    
         
            @Override    
            public void run()    
            {    
                // TODO Auto-generated method stub   
		URL myUrl;
		InputStream i = null;
		Bitmap bitmap=null;
		try{
	        	myUrl = new URL(url);
	        	if(myUrl==null)
	             	return null;
	      
		        URLConnection myconn=myUrl.openConnection();
		        i=myconn.getInputStream();
			bitmap =BitmapFactory.decodeStream(i);
		       
		        i.close();
		        
		        if(bmp==null)
		        	return null;
		   }
		catch(Exception e)
	        {
	        	
	        	e.printStackTrace();
	        	return null;
	        }
               
                imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));    
                Message msg = handler.obtainMessage(0, bitmap);    
                handler.sendMessage(msg);    
               
                File bitmapFile = new File(localImgFullName);    
                if(!bitmapFile.exists())    
                {    
                    try    
                    {    
                        bitmapFile.createNewFile();    
                    }    
                    catch (IOException e)    
                    {    
                        // TODO Auto-generated catch block    
                        e.printStackTrace();    
                    }    
                }    
                FileOutputStream fos;    
                try    
                {    
                    fos = new FileOutputStream(bitmapFile);    
                    bitmap.compress(Bitmap.CompressFormat.PNG,     
                            100, fos);    
                    fos.close();    
                }    
                catch (FileNotFoundException e)    
                {    
                    // TODO Auto-generated catch block    
                    e.printStackTrace();    
                }    
                catch (IOException e)    
                {    
                    // TODO Auto-generated catch block    
                    e.printStackTrace();    
                }    
            }    
        }.start();    
            
        return null;    
    }    
  
    public interface ImageCallBack    
    {    
        public void imageLoad(ImageView imageView, Bitmap bitmap);    
    }    
}  
}   


注意的是在使用的时候,要实现imageCallBack借口
比如在某个地方要使用异步加载图片
AsyncImageLoader asyncBitmapLoader=new AsyncBitmapLoader();  
Bitmap bitmap=asyncBitmapLoader.loadBitmap(image, imageURL,imgPath, new ImageCallBack() {  
                  
                @Override  
                public void imageLoad(ImageView imageView, Bitmap bitmap) {  
                    // TODO Auto-generated method stub  
                    imageView.setImageBitmap(bitmap);  
                }  
            });