2012-01-03 53 views
0
import java.lang.ref.SoftReference; 
import java.util.HashMap; 

import android.graphics.drawable.Drawable; 
import android.os.Handler; 
import android.os.Message; 


public class AsyncImageLoader { 
private HashMap<String, SoftReference<Drawable>> imageCache; 
HashMap<String, SoftReference<Drawable>> drawableMap = new HashMap<String, SoftReference<Drawable>>(); 


public AsyncImageLoader() { 
    //HashMap<String, SoftReference<Drawable>> drawableMap = new HashMap<String, SoftReference<Drawable>>(); 
} 

public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { 

    if (drawableMap.containsKey(imageUrl)) { 
     SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
     Drawable drawable = softReference.get(); 
     if (drawable != null) { 
      return drawable; 
     } 
    } 
    final Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message message) { 
      imageCallback.imageLoaded((Drawable) message.obj, imageUrl); 
     } 
    }; 

    //this is the new thread that download the image from url 
    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; 
} 

public static Drawable loadImageFromUrl(String url) { 
    return null; 
    // ... 
} 

public interface ImageCallback { 
    public void imageLoaded(Drawable imageDrawable, String imageUrl); 
} 

}試圖瞭解以下AyncImageLoader

OK,我的理解是這樣的:
1)檢查是否在緩存中的圖像,如果是則返回繪製; 2)如果不是,則創建一個新的處理程序,以Drawable作爲對象向UI線程發送消息,並且直到調用圖像加載的回調函數時纔會發送該處理程序。 3)創建一個新線程以從url啓動下載圖像。

4) 具體的處理程序的順序發生在這個順序 A)Message message = handler.obtainMessage(0,drawable); B)public void handleMessage(Message message)imageCallback.imageLoaded((Drawable)message.obj,imageUrl); } C)handler.sendMessage(message);

我遇到的問題是數字4,我有點不清楚,獲取消息(0,drawable)?從哪裏獲得?源代碼在哪裏?我怎麼知道它來自哪裏,UI線程或其他?所以,一旦獲得該消息,消息處理程序將執行回調。 public void handleMessage(Message message)imageCallback.imageLoaded((Drawable)message.obj,imageUrl); }

最後它發送帶有drawable的消息作爲有效載荷。 handler.sendMessage(消息); 但我怎麼知道它的發送地點?它是否總是將UI線程作爲最終目的地?

感謝

回答

3

基本上 - 這裏有兩個線程,主UI線程,大多數這段代碼的執行中,並在底部定義的下載線程。

obtainMessage調用只是從一個池中返回一個消息對象,比實例化一個新的更便宜。這與此用法中的構造函數類似。

由於處理程序是在UI線程中定義的,因此handleMessage方法也在UI線程中執行。消息本身只是一種從下載線程獲取drawable到UI線程的方式,並且在下載完成時觸發回調。

所以基本上所有的代碼都是這樣的:如果drawable存在於(SoftReference)緩存中,然後返回它。否則,獲取對處理程序的引用並啓動下載drawable的線程。當該線程完成下載時,它會創建一條消息並將其發送給處理程序,該處理程序依次調用imageCallback.imageLoaded並傳遞新下載的drawable。