Handler 和 AsyncTask 的比较


众所周知,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制。如果不大了解其实现原理的,可以看看这篇文章:Handler详解
不过为了更加方便我们在子线程中对UI进行操作,Android还提供了另外一些好用的工具,AsyncTask就是其中之一。借助AsyncTask,即使你对异步消息处理机制完全不了解,也可以十分简单的从子线程切换到主线程。其实它的实现原理也是同样比较简单的,有兴趣的可以看一下:Android AsyncTask完全解析,带你从源码的角度彻底理解

对与Handler的理解

Handler详解:我觉得这篇文章也可以起到一个深入浅出的作用了

对于AsyncTask的理解

AsyncTask主要有二个部分:一个是与主线各的交互,另一个就是线程的管理调度。虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。与主线程交互是通过Handler来进行的,内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask.execute()后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。对于内部的线程池不同版本的Android的实现方式是不一样的:
在Android 3.0之前:那个时候是直接在AsyncTask中构建了一个sExecutor常量,并对线程池总大小,同一时刻能够运行的线程数做了规定,规定同一时刻能够运行的线程数为5个,线程池总大小为128。也就是说当我们启动了10个任务时,只有5个任务能够立刻执行,另外的5个任务则需要等待,当有一个任务执行完毕后,第6个任务才会启动,以此类推。而线程池中最大能存放的线程数是128个,当我们尝试去添加第129个任务时,程序就会崩溃。如果你的应用需要大量的后台线程去执行任务,那么你只能放弃使用AsyncTask,自己创建线程池来管理Thread,或者干脆不用线程池直接使用Thread也无妨。不得不说,虽然AsyncTask较Thread使用起来比较方便,但是它最多只能同时运行5个线程,这也大大局限了它的实力,你必须要小心的设计你的应用,错开使用AsyncTask的时间,尽力做到分时,或者保证数量不会大于5个,否则就可能遇到上面提到的问题。
**Android 3.0以后:**AsyncTask默认同时只能有1个任务在执行。为什么升级之后可以同时执行的任务数反而变少了呢?这是因为更新后的AsyncTask已变得更加灵活,如果不想使用默认的线程池,还可以自由地进行配置,设置来储存更多的任务,允许同一时刻有更多的任务同时进行。也就是说在Android3.0以后可以自定义线程池。

可以看出,AsyncTask使用过程中需要注意的地方不少:

  1. 由于Handler需要和主线程交互,而Handler又是内置于AsnycTask中的,所以,AsyncTask的创建必须在主线程。
  2. AsyncTaskResult的doInBackground(mParams)方法执行异步任务运行在子线程中,其他方法运行在主线程中,可以操作UI组件。
  3. 不要手动的去调用AsyncTask的onPreExecute, doInBackground, publishProgress, onProgressUpdate, onPostExecute方法,这些都是由Android系统自动调用的
  4. 一个任务AsyncTask任务只能被执行一次。
  5. 运行中可以随时调用cancel(boolean)方法取消任务,如果成功调用isCancelled()会返回true,并且不会执行onPostExecute() 方法了,取而代之的是调用 onCancelled() 方法。而且从源码看,如果这个任务已经执行了这个时候调用cancel是不会真正的把task结束,而是继续执行,只不过改变的是执行之后的回调方法是onPostExecute还是onCancelled。

比较

虽然AsyncTask在底层用到了Handler来实现,但是在一定程度上这两个东西还是不一样的。
AsyncTask不能完全取代线程,在一些逻辑较为复杂或者需要在后台反复执行的逻辑就可能需要线程来实现了。而且在任务复杂的时候,还是比较麻烦,有可能出现问题。
Handler+Thread机制其实完全可以替代AsynTask的这种调用机制。只要将Handler对象传给Thread,就可以进行方便的异步处理。且这种MVC模式结构更加明显,方便管理。所以我觉得,使用asynTask还是Handler+Thread结构,个人喜好吧。但是有一点可以明显能感觉到得是,Handler+Thread适合进行大框架的异步处理,而asynTask适用于小型简单的异步处理。

以上都是个人理解。有新观点请指出。

你可能感兴趣的:(Android)