AsyncTask 原理学习

 一、AsyncTask简单介绍

AsyncTask作用:轻量级的异步类,方便在子线程中更新ui

AsyncTask方法介绍:

onPreExecute():任务执行前调用的方法,可用于做一些准备工作
doInBackground(Object[] objects):异步执行方法,一般用于处理耗时操作
onPostExecute(Object o):异步执行结束后的操作,在主线程中执行,可执行ui操作

简单使用示例:

public class TestAsyncTask extends AsyncTask<String,Integer,Boolean> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Boolean doInBackground(String[] objects) {
        String name0 = (String)objects[0];
        String name1= (String)objects[1];
        Log.d("test",name0  + "   threadId:" + Thread.currentThread().getId()  + "   time:"+ System.currentTimeMillis());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d("test",name1  + "   threadId:"+ Thread.currentThread().getId()  + "   time:"+ System.currentTimeMillis());
        return true;
    }

    @Override
    protected void onPostExecute(Boolean o) {
        super.onPostExecute(o);
        Log.d("test","" + (boolean)o  + "   threadId:" + Thread.currentThread().getId()  + "   time:"+ System.currentTimeMillis());
    }
}

调用示例:

TestAsyncTask task = new TestAsyncTask();
task.execute("test1","test2");

运行打印结果: 

二、AsyncTask原理解释

2.1 、申明

AsyncTask<Params, Progress, Result> 

 参数解释:

Params:启动任务时传入的参数,举例中设置为String,也可设置为其他类型

Progress:任务执行中的进度,一般设置为integer,表示当前处理的进度

Result:处理结果参数,举例中使用的是Boolean

2.2、重要的静态变量

2.2.1、sThreadFactory

AsyncTask重要元素之一,为AsyncTask的线程池创建线程,执行newThread方法的时候会创建线程

 2.2.2、HREAD_POOL_EXECUTOR

定义了一个线程池,线程池 ,注意ThreadPoolExecutor的构造,会将sThreadFactory 存放在成员变量threadFactory,CORE_POOL_SIZE 为1,进程中所有AsyncTask的对象依赖的线程只有一个,按照顺序排队执行task。

2.2.3、SerialExecutor

SerialExecutor的execute方法做了以下两个步骤

1、new了一个runnable对象,并在run方法中执行了参数中runnable的run方法

2、判断mActive是否为空,去执行添加到mTasks中的runnable

2.2.4、mWorker

mWorker,归根结底,就是一个Callable对象,我们再来看他的实现:

注意在他的call方法中执行了doInBackground方法。

2.2.5、mFuture

mFuture,从源头上是实现Runnable以及Future,所以mFuture需要实现Runnable 的run(),也是实现Future的cancel等方法

我们来看一下mFuture的实现以及run方法:

实现mFuture的时候,把mWorker当做了参数并在mFuture中保存了下来,在mFuture的run方法中调用了mWorker.call()方法

2.3、整体流程介绍 

调用AsyncTask.execute(Params... params)方法会执行到以下方法,

 在执行execute()方法之前做了两件事情:

1、执行onPreExecute()做准备工作

2、赋值params给到mWorker.mParams,供2.2.4中调用doInBackground方法使用

 exec对应的是sDefaultExecutor,也就是2.2.3中的SerialExecutor,将2.2.5中的mFuture添加到了SerialExecutor的生成的runnable中,并将生成的runnable添加进了mTasks,调用了THREAD_POOL_EXECUTOR也就是线程池的execute方法。

下面来看线程池的execute方法:

再进入addWorker方法:

以及work的构造方法:

利用2.2.1中的sThreadFactory,去生成了一个thread,并在addworker中执行了thread的run方法。

(说明:work本身也是一个runnable,在run方法中执行了firstTask的run方法)

这样就实现了在新的线程中调用传入的mFuture的run方法,也就是调用了mWorker的call方法,让doInBackground方法在新的线程中执行,实现了异步

2.4、如何实现结果回调到主线程

这儿要注意到另一个金泰变量:sHandler

注意这儿是使用主线程中的looper构造的handler,

在任务执行完之后会调用postResult方法:

在这个方法中,利用handler发送了消息,实现了在主线程中回调onPostExecute或者onCancelled方法。

2.5、最后介绍一下cancel方法防止踩坑

cancel方法如下:

做了两件事:

1、设置 mCancelled为true

2、调用mFuture.cancel()方法

mFuture.cancel()中调用了t.interrupt(),注意t.interrupt()只是尝试去让线程结束,但并不一定能真的结束,所以不能已调用了AsyncTask的cancel方法,判断任务已结束,建议在任务的流程中通过mCancelled这个标识,主动去结束自己的任务流程,比如任务是一个循环,可在循环的时候判断mCancelled为true,去结束循环,进而结束任务

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值