您的位置:首页 > 移动开发 > Android开发

Android异步加载图像小结(1)

2017-05-14 14:52 435 查看
研究了android从网络上异步加载图像,现总结如下:

(1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法。

在主线程中new 一个Handler对象,加载图像方法如下所示

private void loadImage(final String url, final int id) {

handler.post(new Runnable() {

public void run() {

Drawable drawable = null;

try {

drawable = Drawable.createFromStream(new URL(url).openStream(), “image.png”);

} catch (IOException e) {

}

((ImageView) LazyLoadImageActivity.this.findViewById(id)).setImageDrawable(drawable);

}

});

}

上面这个方法缺点很显然,经测试,如果要加载多个图片,这并不能实现异步加载,而是等到所有的图片都加载完才一起显示,因为它们都运行在一个线程中。

然后,我们可以简单改进下,将Handler+Runnable模式改为Handler+Thread+Message模式不就能实现同时开启多个线程吗?

(2)在主线程中new 一个Handler对象,代码如下:

final Handler handler2=new Handler(){

@Override

public void handleMessage(Message msg) {

((ImageView) LazyLoadImageActivity.this.findViewById(msg.arg1)).setImageDrawable((Drawable)msg.obj);

}

};

对应加载图像代码如下:

//采用handler+Thread模式实现多线程异步加载

private void loadImage2(final String url, final int id) {

Thread thread = new Thread(){

@Override

public void run() {

Drawable drawable = null;

try {

drawable = Drawable.createFromStream(new URL(url).openStream(), “image.png”);

} catch (IOException e) {

}

Message message= handler2.obtainMessage() ;

message.arg1 = id;

message.obj = drawable;

handler2.sendMessage(message);

}

};

thread.start();

thread = null;

}

这样就简单实现了异步加载了。细想一下,还可以优化的,比如引入线程池、引入缓存等,我们先介绍线程池。

(3)引入ExecutorService接口,于是代码可以优化如下:

在主线程中加入:private ExecutorService executorService = Executors.newFixedThreadPool(5);

对应加载图像方法更改如下:

// 引入线程池来管理多线程

private void loadImage3(final String url, final int id) {

executorService.submit(new Runnable() {

public void run() {

try {

final Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), “image.png”);

handler.post(new Runnable() {

public void run() {

((ImageView) LazyLoadImageActivity.this.findViewById(id)).setImageDrawable(drawable);

}

});

} catch (Exception e) {

throw new RuntimeException(e);

}

}

});

}

(4)为了更方便使用我们可以将异步加载图像方法封装一个类,对外界只暴露一个方法即可,考虑到效率问题我们可以引入内存缓存机制。详见下一章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android