Android中的线程形态

除了传统的Thread外,还包含AsyncTask,HandlerThread,以及IntentService。

1.AsyncTask:封装了线程池和Handler,它主要是为了方便开发者在子线程中更新UI。

AsyncTask的类必须在主线程中加载,这就意味着第一次访问AsyncTask必须发生在主线程,当然这个果然在Android4.1及以上版本中已经被系统自动完成。在Android5.0的源码中,可以查看ActivityThread的main方法,它会调用AsyncTask的init方法,这就满足了AsyncTask的类必须在主线程中进行加载这个条件了。

AsyncTask的类必须在主线程中创建。

execute方法必须在UI线程调用。

不要在程序中直接调用onPreExecute(),onPostExecute,doInBackground和onProgressUpdate()方法。

一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常。

注意:在Android1.6之前,AsyncTask是串行执行任务的,Android1.6的时候AsyncTask开始采用线程池处理并行任务。但是Android3.0开始,为了避免AsyncTask所带来的并发错误,AsyncTask又采用一个线程来串行执行任务。尽管如此,在Android3.0以及以后的版本中,仍然可以通过AsyncTask的executeOnExecutor()(此方法是Android3.0之后新添加的方法)方法来并行的执行任务。

AsyncTask对THREAD_POOL_EXECUTOR这个线程池的配置如下:

*核心线程数等于CPU核心数+1;

*线程池的最大线程数为CPU核心数的2倍+1;

*核心线程无超时机制,非核心线程在闲置时的超时时间为1秒;

*任务队列的容量为128;

2.HandlerThread:是一种具有消息循环的线程,在它的内部可以使用Handler。

它的实现很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就允许在HandlerThread中创建Handler了,外界需要通过Handler的消息方法来通知HandlerThread执行一个具体的任务。由于HandlerThread的run方法是一个无限循环,因此当明确不需要再使用HandlerThread时,可以通过它的quit或者quitSafely方法来终止线程的执行。

3.IntentService:是一个服务,系统对其进行了封装使其可以更方便的执行后台任务,IntentService内部采用HandlerThread来执行任务,当任务执行完毕后IntentService会自动退出。从任务执行的角度来看,IntentService的作用很想一个后台线程,但是IntentService是一种服务,它不容易被系统杀死从而可以尽量保证任务的执行,而如果是一个后台线程,由于这个时候进程中没有活动的四大组件,那么这个进程的优先级就会非常低,会很容易被系统杀死,这就是IntentService的优点。

它继承了Service并且是一个抽象类,因此必须创建它的子类才能使用IntentService。需要实现onHandleIntent方法。

当任务执行后它会自动停止。

IntentService中的任务是串行排队执行的。

推荐阅读更多精彩内容