Android 多線程網路下載圖片

來源:互聯網
上載者:User

   最近項目中碰到了多線程下載圖片的問題,我自己寫了一個工具類 ImageLoader, 該工具類支援圖片緩衝:有SDCARD緩衝,記憶體緩衝等,支援多線程下載,其具體實現思路為:

 1、實現一個線程池 ExecutorService,將下載多線程的任務添加到該線程池中,可以定義線程池的大小

  2、下載到圖片成功之後,如何通知UI線程去更新UI

 3、圖片的緩衝處理等。

其核心代碼如下:

 

import java.io.File;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;  import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory;import android.text.TextUtils;import android.widget.ImageView;import com.giant.lib.utils.GiantLog;import giant.activity.R;public class ImageLoader {    final int stub_id = R.drawable.default_user_ico;    MemoryCache memoryCache = new MemoryCache();    FileCache fileCache;     private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());    ExecutorService executorService;    private static final String TAG = "ImageLoader";      public ImageLoader(Context context){         fileCache = new FileCache(context);        executorService = Executors.newFixedThreadPool(5);    }     /**     * 顯示圖片需要預設圖片     * @param url     * @param imageView     */    public void DisplayImage(String url, ImageView imageView)    {         imageViews.put(imageView, url);        Bitmap bitmap = memoryCache.get(url);        if(TextUtils.isEmpty(url)){            imageView.setImageResource(R.drawable.default_user_ico);        }//        Bitmap bitmap = null;        if(bitmap!= null)   { //先載入記憶體中的緩衝            imageView.setImageBitmap(bitmap);            GiantLog.d(TAG, "load image data form memory");        }        else        {             queuePhoto(url,imageView);            imageView.setImageResource(stub_id);         }     }    /**     * 顯示圖片不需要預設圖片     * @param url     * @param imageView     */    public void DisplayImageWithNodefault(String url, ImageView imageView)    {        imageViews.put(imageView, url);        Bitmap bitmap = memoryCache.get(url);//        Bitmap bitmap = null;        if(bitmap!= null)   { //先載入記憶體中的緩衝            imageView.setImageBitmap(bitmap);            GiantLog.d(TAG, "load image data form memory");        }        else        {            queuePhoto(url,imageView);           // imageView.setImageResource(stub_id);        }    }    private void queuePhoto(String url, ImageView imageView)    {         PhotoToLoad p = new PhotoToLoad(url,imageView);        executorService.submit(new PhotosLoader(p));     }       private Bitmap getBitmap(String url)    {         File f = fileCache.getFile(url);        //從sd卡        Bitmap b = decodeFile(f);        if(b!=null)  {            GiantLog.d(TAG,"load image from sdcard");            return b;        }        //從網路        try {             Bitmap bitmap = null;            URL imageUrl = new URL(url);             HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();             conn.setConnectTimeout(30000);             conn.setReadTimeout(30000);             conn.setInstanceFollowRedirects(true);             InputStream is = conn.getInputStream();            OutputStream os = new FileOutputStream(f);             Utils.CopyStream(is, os);             os.close();             bitmap = decodeFile(f);            GiantLog.d(TAG,"load image from network" );            return bitmap;         } catch (Exception ex){            ex.printStackTrace();            return null;         }     }      //解碼映像用來減少記憶體消耗    private Bitmap decodeFile(File f){         try {             //解碼映像大小            BitmapFactory.Options o = new BitmapFactory.Options();             o.inJustDecodeBounds = true;             BitmapFactory.decodeStream(new FileInputStream(f),null,o);               //找到正確的刻度值,它應該是2的冪。            final int REQUIRED_SIZE = 70;            int width_tmp = o.outWidth, height_tmp = o.outHeight;            int scale = 1;            while(true){                 if(width_tmp/2 < REQUIRED_SIZE || height_tmp/2 < REQUIRED_SIZE)                    break;                 width_tmp/=2;                 height_tmp/=2;                 scale*=2;             }               BitmapFactory.Options options = new BitmapFactory.Options();            options.inSampleSize = 1;            return BitmapFactory.decodeStream(new FileInputStream(f), null, options);        } catch (FileNotFoundException e) {            GiantLog.d(TAG,"exception:" + e);        }        return null;     }       private class PhotoToLoad     {         public String url;        public ImageView imageView;        public PhotoToLoad(String u, ImageView i){            url = u;            imageView=i;        }    }     class PhotosLoader implements Runnable {         PhotoToLoad photoToLoad;         PhotosLoader(PhotoToLoad photoToLoad){             this.photoToLoad=photoToLoad;         }           @Override        public void run() {             if(imageViewReused(photoToLoad))                 return;             Bitmap bmp = getBitmap(photoToLoad.url);            memoryCache.put(photoToLoad.url, bmp);             if(imageViewReused(photoToLoad))                 return;             BitmapDisplayer bitmapDisplayer = new BitmapDisplayer(bmp, photoToLoad);            Activity activity =(Activity)photoToLoad.imageView.getContext();            activity.runOnUiThread(bitmapDisplayer);        }     }     boolean imageViewReused(PhotoToLoad photoToLoad){         String tag = imageViews.get(photoToLoad.imageView);        return tag == null || !tag.equals(photoToLoad.url);    }      //用於顯示位元影像在UI線程    class BitmapDisplayer implements Runnable     {         Bitmap bitmap;         PhotoToLoad photoToLoad;         public BitmapDisplayer(Bitmap b, PhotoToLoad p)        {   bitmap = b;            photoToLoad = p;        }        public void run()         {             if(imageViewReused(photoToLoad))                 return;             if(bitmap!=null)                 photoToLoad.imageView.setImageBitmap(bitmap);             else                photoToLoad.imageView.setImageResource(stub_id);         }     }    /**     * 清除所有的緩衝(包括記憶體和SD卡)     */    public void clearCache() {         memoryCache.clear();         fileCache.clear();     }    /**     * 只清除記憶體中的緩衝     */    public void clearMemoryCache(){        memoryCache.clear();    }  } 

 

具體使用很簡單:

ImageLoader  imageLoader = new ImageLoader(Activity.this)  ;

 imageLoader.DisplayImageWithNodefault(pic_url,imageVew,false); //不需要顯示預設圖片

 

全部源碼下載連結:

http://download.csdn.net/detail/nanzhiwen666/5955391

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.