AsyncTask - 基础篇

概述

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 - 进阶篇
AsyncTask - 源码篇


专注 Android 技术,不定时推送新鲜文章,如果你有好的文章想和大家分享(有稿费哦),欢迎关注投稿!

技术酱
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容