当前位置: 代码迷 >> Android >> 自己动手写android图片异步加载库(2)
  详细解决方案

自己动手写android图片异步加载库(2)

热度:50   发布时间:2016-04-28 01:16:42.0
自己动手写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;	// config	public int configLoadingImage;// 正在现在时显示的图片id	public int configFailedImage;// 下载失败时显示的资源id	public Type configType = Type.LIFO;// 队列的调度方式	private ExecutorService threadPool;// 线程池	private Tasks task;// 管理任务的队列	// 图片缓存	private LruCache<String, Bitmap> cache;	private Handler mainHandler;// 主线程的handler,修改view	private 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() {			@Override			public 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<Runnable>());		secondSemaphore = new Semaphore(threadNum);		int maxMemory = (int) Runtime.getRuntime().maxMemory();		cache = new LruCache<String, Bitmap>(maxMemory / 8) {			// 测量Bitmap的大小			@Override			protected 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() {			@Override			public 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<Runnable> mTasks;			public Tasks() {		mTasks = new LinkedList<Runnable>();	}	public synchronized void addTask(int flag, Runnable runnable) {		try {			// 请求信号量,防止mPoolThreadHander为null			if ((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();	}}


源码下载



  相关解决方案