AsynTask

作者: Tyler | 来源:发表于2015-10-13 14:57 被阅读189次
  • 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 线程和线程池

    一,Android中的线程形态 AsyncTask AsynTask在具体的使用中的限制(1)AsynTask的类...

  • AsynTask

    AsyncTask为什么要设计为只能够一次任务? 因为要同一个实例执行多次很麻烦,没必要。 假设允许多次 exec...

  • Android AsynTask

    每天一篇系列:强化知识体系,查漏补缺。欢迎指正,共同学习! AsynTask是Android提供的一个轻量级异步任...

  • AsynTask源码分析

    AsynTask介绍 AsyncTask是一个抽象类,有三个泛型参数,四个方法。 Params需要传入的参数 Pr...

  • 2019.6 android面试总结

    hander,AsynTask,okhttp,retrofit原理,尤其是okhttp的几个拦截器作用 strin...

  • Android常见的多线程

    1.继承Thread类; 2.实现Runnable接口。 3.Handler; 4.AsynTask; 5.Han...

  • 【Android 基础】AsynTask 异步任务

    AsynTask 异步任务 Android机制,不允许子线程更新UI界面,耗时操作需要开辟新的Thread执行; ...

  • Handler分析和AsynTask分析

    因为线程简通信经常用到Handler所以这里分析一下,顺便说一下AsynTask。 先说说两个概念: 进程 进程操...

  • android中的异步机制(Handler、Looper、Mes

    关系 AsynTask是获得后台线程的简单方式,但不适合重复且长时间运行的任务。 线程使用的收件箱叫做消息队列(M...

  • 流行框架源码分析(2)-AsynTask源码分析

    主目录见:Android高级进阶知识(这是总目录索引) 国庆的假期刚刚过去,今天就用一篇比较简单的文章来收收心,A...

网友评论

      本文标题:AsynTask

      本文链接:https://www.haomeiwen.com/subject/uhyocttx.html