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();
 - }
 - }
 
这个问题涉及到线程 软引用等
首先当一个程序要显示网络图片时,下载的过程应该是在另外的线程中,那么就需要在其他线程中通知主线程来改变图片的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);
 - }
 - });
 
                    
                
                
            
        
浙公网安备 33010602011771号