Displaying Bitmaps Efficiently之Processing Bitmaps Off the UI Thread
来源:互联网 发布:深圳网络外包公司 编辑:程序博客网 时间:2024/06/18 16:21
我们一般用AsyncTask来loader 图片,避免UI线程ANR。但是AsyncTask是一个抽象类,必须实现子类.
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
由于imageViewReference;是WeakReference,因此要在onPostExtcute方法中判断imageViewReference是否还存在。
怎么使用BitmapWorkerTask 呢?参考如下:
public void loadBitmap(int resId, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(resId);
}
当使用ListView和GridView时,每一个子view 都会触发AsyncTask,没有办法保证这些AsyncTask完成的顺序.或者AsyncTask 完成时,他用于现实的view可能已经被回收了.可以采用下面的方法解决.
可以保存最近使用的AsyncTask的reference,当task完成是可以checkreference。具体code如下:
定义一个bitmapWorkerTaskReference 保存AsyncTask的实例,其采用的WeakReference。
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference =
new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
在执行BitmapWorkerTask的时候,先new一个AsyncDrawable ,然后绑定到目标的ImageView。
public void loadBitmap(int resId, ImageView imageView) {
if (cancelPotentialWork(resId, imageView)) {
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
imageView.setImageDrawable(asyncDrawable);
task.execute(resId);
}
}
cancelPotentialWork 会检查bitmapWorkerTask 是否为NULL,如果不为NULL,则说明有另外一个task在使用这个Imageview。则调用cancel 取消这个先前的task.
public static boolean cancelPotentialWork(int data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) {
final int bitmapData = bitmapWorkerTask.data;
// If bitmapData is not yet set or it differs from the new data
if (bitmapData == 0 || bitmapData != data) {
// Cancel previous task
bitmapWorkerTask.cancel(true);
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
下面这个函数可以取回和AsyncTask 绑定的Imageview.
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
最后一步是更新onPostExecute方法.
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
...
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
final BitmapWorkerTask bitmapWorkerTask =
getBitmapWorkerTask(imageView);
if (this == bitmapWorkerTask && imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
由于imageViewReference;是WeakReference,因此要在onPostExtcute方法中判断imageViewReference是否还存在。
怎么使用BitmapWorkerTask 呢?参考如下:
public void loadBitmap(int resId, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(resId);
}
当使用ListView和GridView时,每一个子view 都会触发AsyncTask,没有办法保证这些AsyncTask完成的顺序.或者AsyncTask 完成时,他用于现实的view可能已经被回收了.可以采用下面的方法解决.
可以保存最近使用的AsyncTask的reference,当task完成是可以checkreference。具体code如下:
定义一个bitmapWorkerTaskReference 保存AsyncTask的实例,其采用的WeakReference。
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference =
new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
在执行BitmapWorkerTask的时候,先new一个AsyncDrawable ,然后绑定到目标的ImageView。
public void loadBitmap(int resId, ImageView imageView) {
if (cancelPotentialWork(resId, imageView)) {
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
imageView.setImageDrawable(asyncDrawable);
task.execute(resId);
}
}
cancelPotentialWork 会检查bitmapWorkerTask 是否为NULL,如果不为NULL,则说明有另外一个task在使用这个Imageview。则调用cancel 取消这个先前的task.
public static boolean cancelPotentialWork(int data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) {
final int bitmapData = bitmapWorkerTask.data;
// If bitmapData is not yet set or it differs from the new data
if (bitmapData == 0 || bitmapData != data) {
// Cancel previous task
bitmapWorkerTask.cancel(true);
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
下面这个函数可以取回和AsyncTask 绑定的Imageview.
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
最后一步是更新onPostExecute方法.
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
...
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
final BitmapWorkerTask bitmapWorkerTask =
getBitmapWorkerTask(imageView);
if (this == bitmapWorkerTask && imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
0 0
- Displaying Bitmaps Efficiently之Processing Bitmaps Off the UI Thread
- Displaying Bitmaps Efficiently(2)-Processing Bitmaps Off the UI Thread
- Displaying Bitmaps Efficiently - Processing Bitmaps Off the UI Thread
- Displaying Bitmaps Efficiently (二)-----Processing Bitmaps Off the UI Thread
- Processing Bitmaps Off the UI Thread
- Processing Bitmaps Off the UI Thread
- Processing Bitmaps Off the UI Thread
- Processing Bitmaps Off the UI Thread
- Processing Bitmaps Off the UI Thread
- Displaying Bitmaps Efficiently之Displaying Bitmaps in Your UI
- [Developer Android] Processing Bitmaps Off the UI Thread
- Displaying Bitmaps Efficiently之Caching Bitmaps
- Displaying Bitmaps Efficiently之Loading Large Bitmaps Efficiently
- Processing Bitmaps Off the UI Thread不在UI线程中处理Bitmaps(Android官方翻译文档2)
- Displaying Bitmaps Efficiently
- Displaying Bitmaps Efficiently
- Displaying Bitmaps Efficiently
- Displaying Bitmaps Efficiently
- Android Service简介(系列1)
- 如何去除有道云笔记广告
- CocoadPods 安装中遇到的一些问题
- 8.2 喀迈拉(no.21~no.30)
- jsp 中右键菜单的操作
- Displaying Bitmaps Efficiently之Processing Bitmaps Off the UI Thread
- Python的GIL
- JAVA类加载(初始化)顺序
- Android-通过SlidingPaneLayout高仿微信6.2最新版手势滑动返回(一)
- POJ-----1274二分图vector
- hdu-3664 Permutation Counting ,dp
- Eclipse调试(1)——基础篇
- c++常见面试题30道
- RTP-RTCP协议分析