先上效果图。第一张图显示的是“相机”文件夹中的所有图片;通过点击多张图片可以到第二张图所示的效果(被选择的图片会变暗,同时选择按钮变亮);点击最下面的那一栏可以到第三张图所示的效果(显示手机中所有包含图片文件的文件夹)。
一、目标
1、尽可能避免内存溢出 A、根据图片的显示大小去压缩图片 B、使用缓存对图片进行管理(LruCache) 2、保证用户操作UI尽可能的流畅 在getView()方法中尽量不做耗时操作(异步显示 + 回调显示) 3、用户预期显示的图片必须尽可能快的显示(图片加载策略的选择:LIFO后进先出 / FIFO先进先出),我们采用采用LIFO(后进先出的策略)
二、思路
1、图片的加载在Adapter的getView()方法中执行,我们根据一个图片的URL到LruCache缓存中寻找Bitmap图片,如果找到则返回图片,如果找不到,则会根据URL产生一个Task并放到TaskQueue中,同时发送一个通知提醒后台轮询线程,轮询线程从TaskQueue中取出一个Task到线程池去执行(执行的是Task的run()方法,具体为:获得图片显示的实际大小;使用Options对图片进行压缩;加载图片且放入LruCache)。我们需要在ImageLoader类中用到:LruCache缓存、线程池、任务列表TaskQueue、后台轮询线程、与轮询线程绑定的Handler和UI线程的Handler
2、具体的实现:Handler + Looper + Message(Android异步消息处理框架)。当我们用Handler发送消息时,会把信息放到MessageQueue中,轮询线程会取出这条消息,交给Handler的handleMessage()方法进行处理
3、后台轮询线程(Thread)不断访问任务队列(LinkList<Runnable>),如果任务队列中有加载图片的任务 (Runnable),就通过Handler发消息给线程池(ExecuterService),让线程池拿出一个子线程,然后根据调度任务的策略 (LIFO)从任务队列中取出一个任务去完成图片的获取,因为图片是异步的在子线程中获取到的,不能直接显示,所以需要通过一个UI相关的Handler把图片对象发送到UI线程中,最后完成图片的显示。
三、代码和解释
(一)目录结构图如下:
(二)代码和解释(解释都在代码的注释中):
未完待续。。。。。。