`
OliveExcel
  • 浏览: 70395 次
文章分类
社区版块
存档分类
最新评论

AsyncTask的用法与分析

阅读更多

今天指导一同事AsyncTask的使用, 然后果断被反指导了. 所以上来记录一下.

 

 先说一下用AsyncTask时要注意的:

      1. AsyncTask要与主线程有交互.

          读代码的时候, 看到有人拿AsyncTask当Thread来用, 实际上是没用到位. 为什么说一定要与主线程有交互? 因为这就是AsyncTask存在的意义. 如果不需要与主线程有交互, 那纯纯的Thread就能解决问题了.

          拿官方文档的话来解释就是: AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

 

      2. AsyncTask下的四个关键方法, 执行在两个不同的线程中.

          a. onPreExecute(), onProgressUpdate(), 以及onPostExecute()系执行在UI thread中;

          b. doInBackground则执行在一个独立的线程中.

          再引用一下官方的话: 官方的话太长了, 去这里找吧: 

          http://developer.android.com/reference/android/os/AsyncTask.html

 

接下来跟着源码的执行, 来尝试分析下AsyncTask, 主要是线程归属方面的东西:

      1. 首先当然是入口execute(), 进去方法里就能看到onPreExecute(). 不用说, onPreExecute()归主线程;

 

      2. 接下来, 还是execute()下面的代码, 注意这么一行:

          sExecutor.execute(mFuture);

          这里的让一个ThreadPoolExecutor去execute()一个FutureTask, 这里做的是什么? 暂且不急着解释. 我们先看看在mFuture里面, 装的是什么东西.

          a. 找到AsyncTask的构造方法, 可以发现mFuture在这里构造时, 所带的参数就是mWorker;

          b. 也就是说, 当到sExecutor执行mFuture的时候, 实际上就是新启动了一个线程, 执行了mWorker;

          c. 再看mWorker, 在它的call()方法下面, 果断调用了doInBackground(). 由此可知, doInBackground(), 实际执行在一个独立的非UI线程下面;

          d. 在doInBackground()调用之后, 将有结果返回. 于是可以通过mFuture下的get()方法, 取到doInBackground()的运行结果;

          e. get()到result后, 通过sHandler, 将result发送给AsyncTask.finish();

          f. 终于, 在finish()方法下, 看到了久违的onPostExecute(). 由于AsyncTask是由主线程创建, 从而可知执行在AsyncTask.finish()方法下的onPostExecute(), 也属于主线程.

          回到前文"暂且不急着解释"的地方, 是否发现, 此处已不存在疑问了? 随着对mFuture代码的走读, 其他部分的逻辑也清晰了起来.

 

      3. 讲到这里貌似应该完了, 回头看看, 还落下了onProgressUpdate().

          这个简单, 想想我们要更新进度时, 需要调用publishProgress(), 一切就明了了. 查看源码, 在publishProgress()中, 向sHandler发送了一条消息, 从而调用了onProgressUpdate(). 那么, onProgressUpdate()属于主线程.

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics