異步下載圖片,同時下載多張圖片

對於進行多線程異步處理的同學應該有很大幫助,先把原帖鏈接拿過來: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);
  }
 }
}

 

發佈了22 篇原創文章 · 獲贊 22 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章