AsyncTask原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AsyncTask原理相关的知识,希望对你有一定的参考价值。

1、对于耗时的操作(如上传下载、读写数据库等),为了不阻塞主线程,我们的一般方法是开启“子线程”。如果需要更新UI,则需要使用handler

2、如果耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。在这种情况下我们就可以考虑使用类AsyncTask来异步执行任务,不需要子线程和handler,就可以完成异步操作和刷新UI。

3、AsyncTask的构造方法有三个模板参数

Params(传递给后台任务的参数类型)

Progress(后台计算执行过程中,进度单位(progress units)的类型,也就是后台程序已经执行了百分之几)

Result(后台执行返回的结果的类型)。

 4、AsyncTask:对线程间的通讯做了轻量级的包装,代码上较之handler更为轻量(实际更耗资源),使用它后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。

      AsyncTask本质上是一个静态的线程池,由它派生出来的子类可以实现不同的异步任务,但这些任务都是提交到该静态线程池中执行,执行的时候通过调用doInBackground()方法执行异步任务,期间会通过Handler将相关的信息发送到UI线程中,但神奇的是,并不是调用UI线程中的回调方法,而是AsyncTask本身就有一个Handler的子类InternalHandler会响应这些消息并调用AsyncTask中相应的回调方法。从上面的代码中我们也可以看到,UI的ProgressBar的更新是在AsyncTask的onProgressUpdate(),而ImageView是在onPostExecute()方法里。这是因为InternalHandler其实是在UI线程里面创建的,所以它能够调用相应的回调方法来更新UI。

      AsyncTask就是专门用来处理后台任务的,而且它针对后台任务的五种状态提供了五个相应的回调接口,使得我们处理后台任务变得非常方便。

      如果只是普通的UI更新操作,像是不断更新TextView这种动态的操作,可以使用Handler,但如果是涉及到后台操作,像是下载任务,然后根据后台任务的进展来更新UI,就得使用AsyncTask,但如果前者我们就使用AsyncTask,那真的是太大材小用了!!

5、两组成部分

一个是与主线各的交互,另一个就是线程的管理调度。虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。

6、使用方法

自定义AsyncTask,在耗时的地方调用自定义的AsyncTask。可以参照以下代码示例。

step1:继承AsyncTask<Params,Progress,Result>

           Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。

           Progress:子线程执行的百分比

           Result:返回值类型。和doInBackground()方法的返回值类型保持一致。

step2:实现以下几个方法:执行时机和作用看示例代码,以下对返回值类型和参数进行说明

          onPreExecute():无返回值类型。不传参数

          doInBackground(Params... params):返回值类型和Result保持一致。参数:若无就传递Void;若有,就可用Params

          publishProgress(Params... params):在执行此方法的时候会直接调用onProgressUpdate(Params... values)

          onProgressUpdate(Params... values):无返回值类型。参数:若无就传递Void;若有,就可用Progress

          onPostExecute(Result  result) :无返回值类型。参数:和Result保持一致。

step3:在调用自定义的AsyncTask类中生成对象;

          执行  :对象.excute(Params... params);

7、基本使用

    protected void onPreExecute()

    protected abstract Result doInBackground(Params... params)

    protected void onPostExecute(Result result)

    protected void onProgressUpdate(Progress... values)

8、源码分析

    private static final int CORE_POOL_SIZE = 5;        //核心线程数

    private static final int MAXIMUM_POOL_SIZE = 128;   //最大线程数

    private static final int KEEP_ALIVE = 1;            //超时时间,当线程数超过核心线程数时,超过这个时间的空线程就会被销毁,直到线程数等于核心线程    

9、缺陷

     9.1 同时只有5个线程去访问网络-->这个是重点

     9.2 线程数目超过128,会抛异常RejectedExecutionException-->这个情况其实还好;

    解决方法:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。

10、版本差异(线程的管理调度方面)

AsyncTask的线程管理调度:内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask#execute()后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。

     10.1 CORE_POOL_SIZE MAXIMUM_POOL_SIZE KEEP_ALIVE在不同的版本上.值是不一样;

     10.2 1.5前是串行执行的.每次执行1个任务

     10.3 1.6-2.3(API4-10)的版本.是并行执行的.每次执行5个任务

     10.4 3.0后提供串行和并行,默认情况是串行

           executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, null);//串行

           executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);//并行

11、简单封装

> 实际开发我们会去继承Asynctask

12、与handler相比

12.1 AsyncTask

优点:简单快捷,过程可控、易于维护;

缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来

12.2 handler

优点:结构清晰,功能定义明确;对于多个后台任务时,简单,清晰

缺点:在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

12.3 AsyncTask是对Thread+Handler良好的封装,在android.os.AsyncTask代码里仍然可以看到Thread和Handler的踪迹

12.4 AsyncTask底层是一个线程池,而handler底层是一个消息队列(可以不开启线程),所以AsyncTask虽然有着更为轻量级的代码,但较之handler更耗资源

13、小结

    13.1 Task的实例必须在UI thread中创建

    13.2 execute方法必须在UI thread中调用

    13.3 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground=\\‘#\\‘" onProgressUpdate(Progress...)这几个方法

    13.4 该task只能被执行一次,否则多次调用时将会出现异常 

    13.5 数据简单使用AsyncTask:实现代码简单;

            数据量多且复杂使用handler+thread:相比较AsyncTask来说能更好的利用系统资源且高效

http://www.cnblogs.com/suinuaner/archive/2013/04/11/android_fifty.html

http://www.cnblogs.com/wenjiang/p/3180324.html

http://blog.csdn.net/hitlion2008/article/details/7983449

以上是关于AsyncTask原理的主要内容,如果未能解决你的问题,请参考以下文章

AsyncTask的原理和缺点

AsyncTask的使用及原理分析

AsyncTask实现机制

异步任务-AsyncTask

Handler研究2-AsyncTask,AsyncQueryHandler分析

Android AsyncTask详解