AsynTask

  • 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 一个成员的话已经泄漏无法访问了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,641评论 25 709
  • 介绍自己负责的部分,如何实现的。 自定义view viewGroup activity的启动流程 事件传递及滑动冲...
    东经315度阅读 5,042评论 1 4
  • Android开发者:你真的会用AsyncTask吗? 导读.1 在Android应用开发中,我们需要时刻注意保证...
    cxm11阅读 7,593评论 0 29
  • 导读:Android面试中高频率出现的题都在这了。试题大部分从互联网收集,博主下了一番功夫进行梳理总结,难免有不足...
    Maat红飞阅读 56,013评论 61 844
  • 总想写点什么,却不知从何写起。每天心中都有个千万个感慨,奈何无处发泄。从网络中每天都能看到许多所谓的鸡汤,其中的故...
    森叟阅读 1,248评论 1 1