在Android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内存溢出。针对上面遇到的两个问题,首先耗费流量我们可以将图片第一次加载上面缓存到本地,以后如果本地有就直接从本地加载。图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略。今天首先介绍一下本地缓存图片。首先看一下异步加载缓存本地代码:
- public class AsyncBitmapLoader
- {
- /**
- * 内存图片软引用缓冲
- */
- private HashMap<String, SoftReference<Bitmap>> imageCache = null;
-
- public AsyncBitmapLoader()
- {
- imageCache = new HashMap<String, SoftReference<Bitmap>>();
- }
-
- public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)
- {
- //在内存缓存中,则返回Bitmap对象
- if(imageCache.containsKey(imageURL))
- {
- SoftReference<Bitmap> reference = imageCache.get(imageURL);
- Bitmap bitmap = reference.get();
- if(bitmap != null)
- {
- return bitmap;
- }
- }
- else
- {
- /**
- * 加上一个对本地缓存的查找
- */
- String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
- File cacheDir = new File("/mnt/sdcard/test/");
- File[] cacheFiles = cacheDir.listFiles();
- int i = 0;
- if(null!=cacheFiles){
- for(; i<cacheFiles.length; i++)
- {
- if(bitmapName.equals(cacheFiles[i].getName()))
- {
- break;
- }
- }
-
- if(i < cacheFiles.length)
- {
- return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);
- }
- }
- }
-
- final Handler handler = new Handler()
- {
- /* (non-Javadoc)
- * @see android.os.Handler#handleMessage(android.os.Message)
- */
- @Override
- public void handleMessage(Message msg)
- {
- // TODO Auto-generated method stub
- imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);
- }
- };
-
- //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
- new Thread()
- {
- /* (non-Javadoc)
- * @see java.lang.Thread#run()
- */
- @Override
- public void run()
- {
- // TODO Auto-generated method stub
- InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
-
- Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
- imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));
- Message msg = handler.obtainMessage(0, bitmap);
- handler.sendMessage(msg);
-
- File dir = new File("/mnt/sdcard/test/");
- if(!dir.exists())
- {
- dir.mkdirs();
- }
-
- File bitmapFile = new File("/mnt/sdcard/test/" +
- imageURL.substring(imageURL.lastIndexOf("/") + 1));
- 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);
- }
- }