当前位置: 代码迷 >> Android >> Android开发点点滴滴——软摘引缓存图片和异步加载
  详细解决方案

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

热度:93   发布时间:2016-04-28 07:48:05.0
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);                  }              });  


  相关解决方案