美文网首页AsyncTask
基于最新版本的AsyncTask详细解读

基于最新版本的AsyncTask详细解读

作者: SilenceDut | 来源:发表于2016-07-21 09:23 被阅读341次

    关于Asnynck有很多的源码解读,但一些解读现在看来已经不在适用了,比如AsyncTask类必须在UI Thread当中加载,AsyncTask的对象必须在UI Thread当中实例化等一些结论都是基于以前版本的代码来解读的,现在看来已经不是这样的了。

    一些结论解读(基于android-23源码):

    • API 16 以前必须在主线程加载 AsyncTask,API 16 以后就不用了。
      因为AsyncTask主要目的是在后台执行异步任务,然后和UI线程进行交互,所以需要得到UI线程的Handler,之前的AsyncTask加载时,是得到当前加载线程的Handler,而最新的源码中,总是得到UI线程的Looper来创建和UI交互的Handler。

    • 因为每个AsyncTask只能执行一次,多次调用同一个AsyncTask对象会出现异常。但如果要处理多个后台任务,你需要创建多个AsyncTask并执行execute()。



      从代码来看,AsyncTask有三种状态,就绪PENDING,运行RUNNING,结束FINISHED,所以只有就绪状态的可以正确执行。可知,每个AsyncTask只能执行一次,所有要想执行多个异步任务,只能新建一个AsyncTask对象。
    • API 4-11 默认是AsnckTask任务并发执行,API11后默认是顺序执行,任务是顺序执行,必须等一个任务结束才能执行下一个。但是可以通过executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)来进行并行执行任务。

      官方注释很详细
      默认线程池
      THREAD_POOL_EXECUTOR是默认的并行执行任务的线程池,BlockingQueue队列的长度是128。以自己的8核手机为例,其核心线程数是9个,最大线程是17,所能最大加入的任务数是128+17=145,如果超出这个任务数,就会报出RejectExecutionException异常(经过测试)。关于线程池的知识更多可看线程池基础
      这也是为什么新的API将任务默认为串行的原因。
    • ** AsyncTask需要在UI线程调用execute()函数 **


      常用函数

      可以看出调用execute()函数时调用了onPreExecute(),而onPreExecute()需要在UI线程中执行,所以AsyncTask需要在UI线程调用execute()函数 。(但是如果你不适用onPreExecute在主线程做一些操作的话,execute()可以在任意线程调用)

    AsyncTask执行任务的过程原理

    AsyncTask的任务执行原理是新建一个有返回值的任务线程FuntureTask和一个Callabler任务,在任务中从doInBackground得到的结果Result通过Handler进行处理,调用onProgress和onPostResult(Result result)关于FuntureTask和Callable更多可看Callable和FutureTask

    初始化对象时建立相应的任务
    execute时执行该任务

    AsyncTask的严重问题及替代方案

    虽然AsyncTask很好用但却又一些问题需要特别注意,详细内容请看详细解读AsyncTask的黑暗面以及一种替代方案

    相关文章

      网友评论

        本文标题:基于最新版本的AsyncTask详细解读

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