二:UI线程外加载图像
1.使用AsyncTask
AsyncTask类提供了一个简单的后台处理方法并将结果返回到UI线程中。
在线程中提议使用WeakReference<?>来缓存显示Bitmap的UI控件,如:ImageView。WeakReference能够确保即使在线程操作时,也能让资源回收器回收UI控件资源,如:ListView回收View资源的情况。
ex:
ImageView imageview = new ImageView(new LayoutParams(100, 100)); //初始化WeakReference WeakReference<ImageView> reference = new WeakReference<ImageView>(imageview); //获取WeakReference存储内容 if(reference != null && reference.get() != null) ImageView imageView = reference.get();
2.处理并发操作(多线程加载)
一些通用的组件(例如ListView和GridView)提倡另一种主流做法,当组件结合AsyncTask来显示内容时,为了有效的利用内存,用户滚动组件后,组件会回收子View资源(超出显示区域的子View)。
如果每一个子View都触发一个AsyncTask,将无法保证当该子View的AsyncTas完成时,该子View尚未被资源回收器回收就被其他子View重用。而且也无法保证异步线程开始的顺序和完成的顺序一致。
接下来这么做:
创建一个BitmapDrawable的继承类(假设为AsyncDrawable)来存储对AsyncTask引用,同样可以用到WeakReference。再执行AsyncTask前,可以先创建AsyncDrawable并绑定到ImageView上。
在进行上一步操作前,需要进行一次校验(如果当前的ImageView为重用的资源且加载的图像资源也一致,就不需要开启线程去加载同样的图像资源了),通过图像资源的标志(如ID,URI)和ImageView(如Drawable),在校验中确定是否取消AsyncTask(调用cancel()方法)。
最后在AsyncTask中需要追加看一个判断,当线程isCancelled()时,结束onPostExecute操作并返还结果,这样便强制结束重用ImageView中的线程。