android Listview 軟引用SoftReference異步加載圖片

HashMap<String, SoftReference<Drawable>> imageCache 關於SoftReference這個類多少知道些機制,會用就ok瞭。

    機制:簡單來說,她會幫助我們管理內存,防止內存溢出,另外一點也就相當於map,臨時緩存些圖片drawable讓我們可以直接引用,很好瞭解決瞭OOM異常.

  

    實現代碼片段:

   

[java]
package com.Tianyou.Mobile.Common; 
 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.ref.SoftReference; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.HashMap; 
 
import com.Tianyou.Mobile.Util.MyUtil; 
 
import android.graphics.Bitmap; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.Handler; 
import android.os.Message; 
 
/***
 * 異步加載圖片 緩存的實現
 * 
 * @author jia
 * 
 */ 
public class AsyncImageLoader { 
    // 軟引用 
    private HashMap<String, SoftReference<Drawable>> imageCache; 
 
    public AsyncImageLoader() { 
        imageCache = new HashMap<String, SoftReference<Drawable>>(); 
    } 
 
    /***
     * 下載圖片
     * 
     * @param imageUrl
     *            圖片地址
     * @param imageCallback
     *            回調接口
     * @return
     */ 
    public Drawable loadDrawable(final String imageUrl, 
            final ImageCallback imageCallback) { 
        if (imageCache.containsKey(imageUrl)) { 
            SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
            Drawable drawable = softReference.get(); 
            if (drawable != null) { 
                return drawable; 
            } 
        } 
        final Handler handler = new Handler() { 
            public void handleMessage(Message message) { 
                imageCallback.imageLoaded((Drawable) message.obj, imageUrl); 
            } 
        }; 
        // 開啟線程下載圖片 
        new Thread() { 
            @Override 
            public void run() { 
                Drawable drawable = loadImageFromUrl(imageUrl); 
                // 將下載的圖片保存至緩存中 
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); 
                Message message = handler.obtainMessage(0, drawable); 
                handler.sendMessage(message); 
            } 
        }.start(); 
        return null; 
    } 
 
    /***
     * 根據URL下載圖片(這裡要進行判斷,先去本地sd中查找,沒有則根據URL下載,有則返回該drawable)
     * 
     * @param url
     * @return
     */ 
    public static Drawable loadImageFromUrl(String imageURL) { 
 
        Bitmap bitmap = MyUtil.GetBitmap(imageURL, 100); 
        Drawable drawable = new BitmapDrawable(bitmap); 
        return drawable; 
 
    } 
 
    // 回調接口 
    public interface ImageCallback { 
        public void imageLoaded(Drawable imageDrawable, String imageUrl); 
    } 
 

     上面這個類斯通見慣瞭,大部分都是這樣實現的,我現在要講一點,也是迷惑我很久瞭一點(回調接口運用)本人基礎不好,所以卡在這裡瞭,
     在listview中的getview方法中要調用這個方法:

     代碼片段:

[java] 
public Drawable getDrawable(AsyncImageLoader asyncImageLoader, 
            String imageUrl, final ImageView imageView) { 
        Drawable drawable = asyncImageLoader.loadDrawable(imageUrl, 
                new ImageCallback() { 
                    @Override 
                    public void imageLoaded(Drawable imageDrawable, 
                            String imageUrl) { 
                        if (imageDrawable != null) 
                            imageView.setImageDrawable(imageDrawable); 
                        else 
                            imageView.setImageResource(R.drawable.u6_normal); 
                    } 
                }); 
        return drawable; 
    } 
  這個方法作用:獲取軟用中的圖片,其實在我們首次進入listview中的時候,軟應用是不起作用的,隻是用來下載圖片保存至sd卡和軟引用中.這個方法就是執行瞭這些操作,對於參數imageView 就是在要把獲取的drawable設置進去.
   執行的順利:首先我們調用的是loadDrawable這個方法,然後查找軟引用中有沒有該drawable,沒有的話則線程下載,下載ok後會執行handleMessage中imageCallback.imageLoaded((Drawable) message.obj, imageUrl);然後執行我們已經實現瞭這個接口.

     在getiview 中執行代碼片段:

    
[java] 
Drawable drawable = getDrawable(asyncImageLoader, Image_L, 
                holder.iv_image); 
         
        if(drawable!=null) 
            holder.iv_image.setImageDrawable(drawable); 
   當我們下滑動後,然後在上滑動的時候軟應用起到瞭效果,效率很快哦,可以和新浪聘美瞭,呵呵,玩笑,要優化的地方還很多.

 作者:jj120522

發佈留言