在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);
- }
- }