對於進行多線程異步處理的同學應該有很大幫助,先把原帖鏈接拿過來:http://www.eoeandroid.com/thread-210082-1-1.html下面上我測試後的截圖,五張圖片,一次下載完成。如果使用handler+Thread+MessageQueen的話,必須要等到一張圖片下載完成,線程處於空閒狀態才能下載第二幅圖片。這個實例使用的是Handler+ExecutorService(線程池)+MessageQueue+本地緩存模式。他的好處是多個圖片可以一次下載完成,線程直接是異步的,增加本地緩存模式可以有效放在重複下載已經下載完成的圖片,節省手機內存空間,同時提高了想效率
源代碼如下:
核心代碼,多線程異步下載加雙緩存:
package com.marller.asyncimageloader;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.graphics.drawable.Drawable;
import android.os.Handler;
public class AsyncImageLoader {
private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
private ExecutorService mExeCutorService = Executors.newFixedThreadPool(5);
private final Handler handler = new Handler();
public Drawable getDrawable(final String imageUrl,
final ImageCallback callback) {
// 如果緩存過就從緩存中取出數據
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
}
// 緩存中沒有圖像,則從網絡上取出數據,並將取出的數據緩存到內存中
mExeCutorService.submit(new Runnable() {
public void run() {
try {
final Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<Drawable>(
drawable));
handler.post(new Runnable() {
public void run() {
callback.imageLoaded(drawable);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return null;
}
// 從網絡上取數據方法
protected Drawable loadImageFromUrl(String imageUrl) {
try {
return Drawable.createFromStream(new URL(imageUrl).openStream(),
"image.jpg");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 對外界開放的回調接口
public interface ImageCallback {
// 注意 此方法是用來設置目標對象的圖像資源
public void imageLoaded(Drawable imageDrawable);
}
}
利用上面的下載公爵開始測試:
package com.marller.asyncimageloader;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadImage(
"http://a.hiphotos.baidu.com/image/q%3D100%3Ba0%3D+%2C1%2C1/sign=e02416c1c1fdfc03e378e7b8e404e6a4/eac4b74543a98226e724cb188882b9014a90eb2c.jpg",
R.id.imageView1);
loadImage(
"http://b.hiphotos.baidu.com/image/q%3D85%3Ba0%3D+%2C1%2C1/sign=f8f331ac4ec2d562f408dde8dc70a0d2/d833c895d143ad4b90d8d90c83025aafa50f0603.jpg",
R.id.imageView2);
loadImage(
"http://e.hiphotos.baidu.com/image/q%3D100%3Ba0%3D+%2C1%2C1/sign=69d9640f38f33a87986d041af6677108/cf1b9d16fdfaaf514f3e66808e5494eef01f7a34.jpg",
R.id.imageView3);
loadImage(
"http://d.hiphotos.baidu.com/pic/w%3D230/sign=42483bc35266d0167e19992ba72ad498/f703738da9773912c8883d6ff8198618367ae216.jpg",
R.id.imageView4);
loadImage(
"http://b.hiphotos.baidu.com/pic/w%3D230/sign=b19458e464380cd7e61ea5ee9145ad14/f2deb48f8c5494eef1f5a84d2cf5e0fe98257e8a.jpg",
R.id.imageView5);
}
private AsyncImageLoader asyncImageLoader = new AsyncImageLoader();
// 引入線程池,並引入內存緩存功能,並對外部調用封裝了接口,簡化調用過程
private void loadImage(final String url, final int id) {
// 如果緩存過就會從緩存中取出圖像,ImageCallback接口中方法也不會被執行
Drawable cacheImage = asyncImageLoader.getDrawable(url,
new AsyncImageLoader.ImageCallback() {
// 請參見實現:如果第一次加載url時下面方法會執行
public void imageLoaded(Drawable imageDrawable) {
((ImageView) findViewById(id))
.setImageDrawable(imageDrawable);
}
});
if (cacheImage != null) {
((ImageView) findViewById(id)).setImageDrawable(cacheImage);
}
}
}