AsyncTask - 基础篇

作者: CokeNello | 来源:发表于2019-03-16 13:22 被阅读0次

概述

AsyncTask,Android早期推介处理异步任务的类,虽然现在有很多种方式去处理异步任务,如RX,三方库等等,但还是建议大家了解一下这个基础的原生类,毕竟熟悉源码,扎实自己的基础和对面试也有很大帮助。

AsyncTask是一个轻量级选手,适合处理轻量级的后台任务。处理过程中还可以把处理的进度反馈到主线程中,方便我们更新UI,不需要我们去操作 handler,在早期 Android 版本中是十分方便的工具。

1. 了解 AsyncTask 的泛型

使用 AsyncTask 我们需要继承:
public abstract class AsyncTask<Params, Progress, Result>
其需要我们定义三个参数泛型:

  • Params,输入参数,执行任务时发送到后台任务的参数类型
  • Progress,后台任务执行时,更新进度的参数类型
  • Result,后台任务执行完毕的输出结果

2. 实现 doInBackground

继承后我们需要实现 doInBackground 这个方法,顾名思义,其跑在子线程,在里面我们可以肆无忌惮地进行耗时的操作:

private static class MyAsyncTask extends AsyncTask<String,Integer,Boolean> {
    @Override
    protected Boolean doInBackground(String... strings) {
        //do some thing
        return true;
    }
}

doInBackground 是核心,其传入参数类型,就是我们继承时候定义的三个泛型中的:Params,其最后return的类型就是我们定义的泛型 Result。doInBackground 跑在子线程中,那我们怎么更新进度呢?怎么更新UI呢?在哪里更新呢?

3. 任务执行进度更新

如果我们需要在 doInBackgroud 的耗时操作中,及时地回调执行任务的进度,我们可以直接调用方法 pulishProgress 来进行,pulishProgress 需要传入一个参数,这个参数就是我们一开始定义的泛型:progress:

    /**
     * 后台任务处理方法,运行在
     * 子线程,可以做一些耗时任务
     * @param strings 输入参数,对应于泛型:Params
     * @return 结果
     */
    @Override
    protected Boolean doInBackground(String... strings) {
        Log.i(TAG,"doInBackground...");
        int i=0;
        while(i<100){
            if (isCancelled())
                break;
            i++;
            //任务执行过程进度/参数的回调,对应于泛型:Progress
            publishProgress(i);
            try {
                Thread.sleep(200);
            } catch (InterruptedException ignored) {
            }
        }
        //返回值代表最后的结果,对应于泛型:Result
        return true;
    }

通过 publishProgress 更新的进度值,最后会回调到方法 onProgressUpdate 中,我们重写这个方法,在里面做UI更新:

    /**
     * 任务执行过程中的更新,
     * 由子方法:publishProgress()
     * 触发,运行在UI线程中
     * @param values 参数
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        TextView tvProgress = textViewWeakReference.get();
        ProgressBar progressBar = progressBarWeakReference.get();
        if (tvProgress!=null)
            tvProgress.setText(values[0]+"%");
        if (progressBar!=null)
            progressBar.setProgress(values[0]);
    }

4. 任务的开启和取消

  • 任务开启:
myAsyncTask = new MyAsyncTask(TestAsyncTaskActivity.this,progressBar,tvProgress);
myAsyncTask.execute("start");
  • 任务取消,这里需要传入一个参数:如果传入的是false并且 doInBackgroud 已经开始执行,当前任务是不会被终止的,而是会继续执行直到异常或者执行完毕,如果未开始,是可以被终止的。如果传入的是true,会调用当前线程的interrupt()方法,把中断标志位设为true,最终会调用到,FutureTask 里面的 cancel 方法,可这样真的会被终止吗?可不一定,可以看看这篇文章:FutureTask介绍及使用
if (myAsyncTask!=null)
    myAsyncTask.cancel(true);

5. 其他重要的方法

  • protected void onPreExecute()
    任务执行开启之前回调,即在doInBackgroud 方法前被调用
    ,运行在UI线程,可以在这里做一些参数的初始化

  • protected void onPostExecute(Boolean bool)
    任务执行结束的回调,运行在UI线程,入参就是在继承类的时候,定义的泛型 Result。

  • protected void onCancelled()
    执行 task.cancel() 方法后,onPostExecute 这个方法不会被回调,取而代之,被回调的是 onCancelled 方法,其运行在UI线程。

6. 总结

本篇主要的目的是让大家了解到 AsyncTask 的基础用法,主要是要掌握其三个泛型的作用,以及泛型对应到哪个方法里面,还有最重要的是,清楚掌握每个方法回调的线程和其作用,还有 AsyncTask 任务从开始到结束的生命周期:

image.png

看起来 AsyncTask 好像还挺好用的,但其实有很多坑,我们下一篇再说。


喜欢分享吗?欢迎投稿 ~ 有稿费呢

技术酱

相关文章

  • AsyncTask - 基础篇

    概述 AsyncTask,Android早期推介处理异步任务的类,虽然现在有很多种方式去处理异步任务,如RX,三方...

  • AsyncTask源码分析

    上一篇我们分析了Handler的源码,这一篇我们来看一下AsyncTask,AsyncTask本身也是通过Hand...

  • 基础疑问:AsyncTask

    AsyncTask用于什么场景? 提供了一种简洁的方式去处理异步任务。因为代码很集中。不像handler那样分散。...

  • AsyncTask基础理解

    AsyncTask 封装好的异步消息处理机制 属于抽象类,需要创建子类继承AsyncTask。 开启子线程执行耗时...

  • Android AsyncTask基础

    AsyncTask是Android为了简化异步操作而封装的异步任务操作抽象类。当我们需要在程序中执行耗时的异步操作...

  • AsyncTask基础一

    类的使用 AsyncTask 是一个抽象类,需要被继承,继承AsyncTask需要指定如下三个泛型参数: 构建其子...

  • Android必学-AsyncTask基础

    Android必学-AsyncTask基础http://www.imooc.com/learn/377 githu...

  • Android获取本地视频文件的截图

    上次在异步之AsyncTask(一)中我们讲了AsyncTask的基础,这次来再结合新的功能来巩固一下知识点. 阅...

  • Android AsyncTask详解(源码分析)

    之前有写过一篇博客,关于Android AsyncTask使用方法 AsyncTask 的使用方法,想着不能又是知...

  • Android日记之AsyncTask源码解析

    前言 AsyncTask的使用方法请看Android日记之AsyncTask的基本使用,此篇的源码解析我们还是从使...

网友评论

    本文标题:AsyncTask - 基础篇

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