对于进行多线程异步处理的同学应该有很大帮助,先把原帖链接拿过来: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
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
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));
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);
}
}
}