詳細解說Android 異步加載圖片

jopen 11年前發布 | 19K 次閱讀 Android 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);
}
}
});
}
</span>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!