-
AsyncTask为什么要设计为只能够一次任务?
因为要同一个实例执行多次很麻烦,没必要。
假设允许多次 execute 同一个 AsyncTask 多次,也就是说队列中会有同一个 AsyncTask 实例出现多次。首先 AsyncTask 需要改动很多,比如把各种状态额外保存多份,不能像现在这样简单做为 AsyncTask 的成员变量,这些先不说,从调用者角度来看:
你继承 AsyncTask 实现了自己的一个子类 MyTask,加了一些成员变量,你想多次执行同一个 MyTask,发现不对啊,我第一次执行后这些成员变量的值都变了,状态不对。还得加个 reset 函数把这些值改回初使值,再一想何必呢,我干脆重新 new 一个 MyTask 不是更简单有效吗。
另外,虽然用默认的 Executor 是不会同时运行的,但你 execute 时如果用了自己定义 Executor,是有可能会多线程同时访问的。这时你也会想还要搞线程同步太麻烦了还是我还是 new 两个 MyTask 别想着同一个 MyTask 运行两次好了。
所以,你看,就算人家允许你同一个 AsyncTask execute 多次,你既然也不会用这功能的话,我就干脆不许你 execute 两次好了。
-
AsynTask造成的内存泄露的问题怎么解决,比如任务还在请求中,但这个Activity已经被销毁了,这个task就仍然持有act的引用,造成内存泄露?
最主要的是在 Activity 销毁时就应该把所有属于这个 Activity 的 Task cancel 掉。
你的 Task 应该在 onCancelled 函数中做相应的处理。比如说如果 Task 是用 来联网的,就应该在 onCancelled 中 disconnect。然后在 onCancelled 中将指向 Activity 的引用设为 null;
弱引用更多的是一份保险,保证如果你在没有正确 cancel Task 时,不会让本应去死的 Activity 还因为 Task 的引用还在内存中晃悠。当然这个保险是很有必要的。
弱引用Demo:
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();
}
}
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);
}
}
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;
}
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;
}
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);
}
}
}
}
-
task执行完返回结果在已经被销毁的act显示,会如何?
如果执行了这个 activity 的 view 的操作的话,会报异常。因为此时这个 view 已经不属于任何活的Window。
-
Act销毁但Task如果没有销毁掉,当Act重启时这个task该如何解决?
最多就是 Task 指向 Activity 的引用改成弱引用了。 Task 如果是 Activity 一个成员的话已经泄漏无法访问了。
网友评论