Android源码分析—带你认识不一样的AsyncTask

来源:互联网 发布:macbookpro看视频软件 编辑:程序博客网 时间:2024/05/06 08:12

前言

什么是AsyncTask,相信搞过android开发的朋友们都不陌生。AsyncTask内部封装了Thread和Handler,可以让我们在后台进行计算并且把计算的结果及时更新到UI上,而这些正是Thread+Handler所做的事情,没错,AsyncTask的作用就是简化Thread+Handler,让我们能够通过更少的代码来完成一样的功能,这里,我要说明的是:AsyncTask只是简化Thread+Handler而不是替代,实际上它也替代不了。同时,AsyncTask从最开始到现在已经经过了几次代码修改,任务的执行逻辑慢慢地发生了改变,并不是大家所想象的那样:AsyncTask是完全并行执行的就像多个线程一样,其实不是的,所以用AsyncTask的时候还是要注意,下面会一一说明。另外本文主要是分析AsyncTask的源代码以及使用时候的一些注意事项,如果你还不熟悉AsyncTask,请先阅读android之AsyncTask 来了解其基本用法。

这里先给出AsyncTask的一个例子:

 

使用AsyncTask的规则

  • AsyncTask的类必须在UI线程加载(从4.1开始系统会帮我们自动完成)
  • AsyncTask对象必须在UI线程创建
  • execute方法必须在UI线程调用
  • 不要在你的程序中去直接调用onPreExecute(), onPostExecute, doInBackground, onProgressUpdate方法
  • 一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常
  • AsyncTask不是被设计为处理耗时操作的,耗时上限为几秒钟,如果要做长耗时操作,强烈建议你使用Executor,ThreadPoolExecutor以及FutureTask
  • 在1.6之前,AsyncTask是串行执行任务的,1.6的时候AsyncTask开始采用线程池里处理并行任务,但是从3.0开始,为了避免AsyncTask所带来的并发错误,AsyncTask又采用一个线程来串行执行任务

AsyncTask到底是串行还是并行?

给大家做一下实验,请看如下实验代码:代码很简单,就是点击按钮的时候同时执行5个AsyncTask,每个AsyncTask休眠3s,同时把每个AsyncTask执行结束的时间打印出来,这样我们就能观察出到底是串行执行还是并行执行。

 我找了2个手机,系统分别是4.1.1和2.3.3,按照我前面的描述,AsyncTask在4.1.1应该是串行的,在2.3.3应该是并行的,到底是不是这样呢?请看Log

Android 4.1.1上执行:从下面Log可以看出,5个AsyncTask共耗时15s且时间间隔为3s,很显然是串行执行的

20131227020312906

Android 2.3.3上执行:从下面Log可以看出,5个AsyncTask的结束时间是一样的,很显然是并行执行

20131227020343265

结论:从上面的两个Log可以看出,我前面的描述是完全正确的。下面请看源码,让我们去了解下其中的原理。

让你的AsyncTask在3.0以上的系统中并行起来

通过上面的源码分析,我已经给出了在3.0以上系统中让AsyncTask并行执行的方法,现在,让我们来试一试,代码还是之前采用的测试代码,我们要稍作修改,调用AsyncTask的executeOnExecutor方法而不是execute,请看:

 

下面是系统为4.1.1手机打印出的Log:很显然,我们的目的达到了,成功的让AsyncTask在4.1.1的手机上并行起来了,很高兴吧!希望这篇文章对你有用。

async3

0 1