逻辑上是指以多线程的方式处理操作,Android API层面上是指AsyncTask类。

AsyncTask的优点

当我们通过线程去执行耗时的任务,并且在操作完之后可能还有更新UI时,通常还会用到Handler来更新UI线程。虽然其实现起来简单,但是如果有多个任务同时执行时则会显得代码臃肿。Android提供了AsyncTask,它使得异步任务实现起来更加简单,代码更简洁。

AsyncTask的使用

AsyncTask是一个抽象的泛型类,它有3个泛型参数,分别为Params、Progress和Result,其中Params为参数类型,Progress为后台任务执行进度的类型,Result为返回结果的类型。如果不需要某个参数,可以将其设置为Void类型。AsyncTask中有4个核心方法,如下所示。

  1. onPreExecute():在主线程中执行。一般在任务执行前做准备工作,比如对 UI 做一些标记。
  2. doInBackground(Params…params):在线程池中执行。在 onPreExecute方法执行后运行,用来执行较为耗时的操作。在执行过程中可以调用publishProgress(Progress…values)来更新进度信息。
  3. onProgressUpdate(Progress…values):在主线程中执行。当调用publishProgress(Progress…values)时,此方法会将进度更新到UI组件上。
  4. onPostExecute(Result result):在主线程中执行。当后台任务执行完成后,它会被执行。doInBackground方法得到的结果就是返回的result的值。此方法一般做任务执行后的收尾工作,比如更新UI和数据。

AsyncTask源码解析

// TODO

AsyncTask的缺点

线程池里面的每个线程存放的都是 MobileAPI 的调用请求,而 AsyncTask 中又没有暴露 出取消这些请求的方法,也就是我们熟知的 CancelRequest 方法,所以,一旦从 A 页面跳转 到 B 页面,那么在 A 页面发起的 MobileAPI 请求,如果还没有返回,并不会被取消。 对于一款频繁调用 MobileAPI 的应用类 App 而言,最严重的情况发生在首页到二级页面 的跳转,因为在首页会调用十几个 MobileAPI 接口,视网络情况而定,如果是 WiFi,应该很 快就能请求到数据,不会产生积压,但如果是 3G 或者 2G,那么请求就会花费很长时间,而 我们在这期间就跳转到二级页面,而这个二级页面也会调用 MobileAPI 接口,那么将得不到 任何结果,因为首页的请求还在排队处理中,之前的那十几个 MobileAPI 接口的数据还都遥 遥无期在线程池里排队呢,就更不要说当前页面这个请求了。 如果你不信,我们可以做个试验。记录每次 MobileAPI 请求发起和接收数据的时间点, 你会看到,在迅速进入二级页面后,首页的十几个 MobileAPI 请求只有发起时间并没有返回 时间,说明它们还在处理过程中,都被堵塞了 。