自己動手寫android圖片非同步載入庫(二)

來源:互聯網
上載者:User

自己動手寫android圖片非同步載入庫(二)

在《自己動手寫android圖片非同步載入庫》系列的第一篇文章中,主要是學習了使用ReferenceQueue來實現一個記憶體緩衝。在這篇文章中主要是介紹在下載很多圖片是怎麼控制線程和隊列。在這版代碼裡,加入訊號量和隊列,可以控制下載任務的順序、可以控制暫停和結束。

代碼A:ImageLoader.java

 

/** * 圖片載入工具類 *  * @author qingtian * @blog http://blog.csdn.net/bingoSpunky */@SuppressLint(HandlerLeak)public class ImageLoader {private int flag = 0;public static int FLAG_FINISHED_INIT_SECOND_THREAD = 0X1;private static final int DEFAULT_THREAD_COUNT = 2;private static final int SUCCESS = 1;private static final int FAILED = 0;// configpublic int configLoadingImage;// 正在現在時顯示的圖片idpublic int configFailedImage;// 下載失敗時顯示的資源idpublic Type configType = Type.LIFO;// 隊列的調度方式private ExecutorService threadPool;// 線程池private Tasks task;// 管理工作的隊列// 圖片緩衝private LruCache cache;private Handler mainHandler;// 主線程的handler,修改viewprivate Handler secondHandler;//private volatile Semaphore secondSemaphore;// 訊號量控制第二條線程發送的正在執行且沒執行完的線程的數量==線程池的數量public ImageLoader() {this(DEFAULT_THREAD_COUNT);}public ImageLoader(int threadNum) {task = new Tasks();new Thread() {public void run() {Looper.prepare();secondHandler = new Handler() {public void handleMessage(android.os.Message msg) {try {secondSemaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();}threadPool.execute(task.getTask(configType));};};flag |= FLAG_FINISHED_INIT_SECOND_THREAD;task.mSemaphore.release();Looper.loop();};}.start();mainHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {ImgBeanHolder holder;switch (msg.what) {case SUCCESS:holder = (ImgBeanHolder) msg.obj;ImageView imageView = holder.imageView;Bitmap bm = holder.bitmap;String uri = holder.uri;Object tag = imageView.getTag();if (holder!=null&&holder.listener != null) {if (tag != null && tag.toString().equals(uri)) {holder.listener.onSuccess(imageView, true, bm, uri);} else {holder.listener.onSuccess(imageView, false, bm, uri);}LogUtils.d(載入失敗    載入圖片    uri:+holder.uri);}break;case FAILED:holder = (ImgBeanHolder) msg.obj;if (holder.listener != null) {holder.listener.onFailed();LogUtils.d(載入成功    載入圖片    uri:+holder.uri);}break;}}};threadPool = new ThreadPoolExecutor(threadNum, threadNum, 0,TimeUnit.SECONDS, new LinkedBlockingDeque());secondSemaphore = new Semaphore(threadNum);int maxMemory = (int) Runtime.getRuntime().maxMemory();cache = new LruCache(maxMemory / 8) {// 測量Bitmap的大小@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getRowBytes() * value.getHeight();}};}public void display(ImageView iv, String uri) {display(iv, uri, new SimpleImageLoaderListener());}public void display(final ImageView iv, final String uri,final ImageLoaderListener imageLoaderListener)throws RuntimeException {if (imageLoaderListener == null) {throw new RuntimeException(imageLoaderListener不可為空);}iv.setTag(uri);showDefalutImage(iv);task.addTask(flag, new Runnable() {@Overridepublic void run() {LogUtils.d(開始    載入圖片    uri:+uri);Bitmap bm = cache.get(uri);if (bm != null) {LogUtils.d(在記憶體緩衝    載入圖片    uri:+uri);sendMessageToMainHandler(SUCCESS, bm, iv, uri,imageLoaderListener);} else {ImageSize imageSize = ImageViewUtil.getImageViewWidth(iv);LogUtils.d(通過網路    載入圖片     uri:+uri);bm = BitmapUtil.decodeSampledBitmapFromResource(uri,imageSize.width, imageSize.height);// bm = BitmapUtil.getImageBitmap(uri);if (bm != null) {cache.put(uri, bm);sendMessageToMainHandler(SUCCESS, bm, iv, uri,imageLoaderListener);} else {sendMessageToMainHandler(FAILED, bm, iv, uri,imageLoaderListener);}}secondSemaphore.release();}});secondHandler.sendEmptyMessage(0x123);}@SuppressWarnings(deprecation)private static BitmapDrawable mBitmapDrawable = new BitmapDrawable();public void showDefalutImage(ImageView iv){if (configLoadingImage != 0) {iv.setImageResource(configLoadingImage);}else{iv.setImageDrawable(mBitmapDrawable);}}public void stop() {task.stop();}public void restart() {task.start();}public void cancel() {task.cancel();}/** * 向主線程的handler發送message */private void sendMessageToMainHandler(int what, Bitmap bm, ImageView iv,String uri, ImageLoaderListener imageLoaderListener) {ImgBeanHolder holder = new ImgBeanHolder();holder.bitmap = bm;holder.imageView = iv;holder.uri = uri;holder.listener = imageLoaderListener;Message msg = Message.obtain();msg.what = what;msg.obj = holder;mainHandler.sendMessage(msg);}public class ImgBeanHolder {Bitmap bitmap;ImageView imageView;String uri;ImageLoaderListener listener;}}

代碼B:Tasks.java

 

 

public class Tasks {public boolean starting = true;public enum Type{FIFO, LIFO}/** * 引入一個值為1的訊號量,防止mPoolThreadHander未初始化完成 */public volatile Semaphore mSemaphore = new Semaphore(0);/** * 任務隊列 */private LinkedList mTasks;public Tasks() {mTasks = new LinkedList();}public synchronized void addTask(int flag, Runnable runnable) {try {// 請求訊號量,防止mPoolThreadHander為nullif ((flag & ImageLoader.FLAG_FINISHED_INIT_SECOND_THREAD) == 0)mSemaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();}mTasks.add(runnable);}public volatile Semaphore startingSemaphore = new Semaphore(0);/** * 取出一個任務 */public synchronized Runnable getTask(Type type) {if(!starting){try {LogUtils.d(wait());wait();} catch (InterruptedException e) {e.printStackTrace();}}if (type == Type.FIFO) {return mTasks.removeFirst();} else if (type == Type.LIFO) {return mTasks.removeLast();}return null;}public synchronized void start(){if(!starting){starting = true;this.notify();LogUtils.d(start notify());}}public synchronized void stop(){if(starting){LogUtils.d(stop());starting = false;}}/** * 取消所有任務 */public synchronized void cancel(){mTasks.clear();}}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.