Android的线程和线程池
1、背景
Android中,线程分为主线程和子线程,主线程主要处理和界面相关的事情,而子线程则往往用于执行耗时操作。
除了Thread本身以外,在Android中可以扮演线程角色还有AsynTask和IntentService,同时HandlerThread也是一种特殊的线程。
对于AsynTask来说,它的底层用到了线程池,AsynTask封装了线程池和Handler,主要是为了方便开发者在子线程中更新UI。
对于IntentService和HandlerThread,它们的底层则直接使用了线程。HandlerThread是一种具有消息循环的线程,在它的内部可以使用Handler。
IntentService是一个服务,系统对其进行了封装使其可以更方便地执行后台任务,IntentService内部采用HandlerThread来执行任务,当任务执行完毕后IntentService会自动退出。
Android主线程的作用是运行四大组件以及处理它们和用户的交互,而子线程的作用则是执行耗时任务,比如网络请求,io操作等。
2、AsyncTask
AsyncTask是一种轻量级的异步任务类,可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新UI。AsyncTask不适合进行特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池。
AsyncTask是一个抽象的泛型类:
public abstract class AsyncTask<Params,Progress,Result>
提供了四个核心方法:
a、onPreExecute(),在主线程中执行,在异步任务执行之前,此方法会被调用,一般可以用于做一些准备工作。
b、doInBackground(Params ... params), 在线程池中执行,此方法用于执行异步任务。可以通过publishProgress方法来更新任务的进度,publishProgress会调用onProgressUpdate方法。此外此方法需要返回结果给onPostExecute方法。
c、onProgressupdate(Progress ...values),在主线程中执行,当后台任务的执行进度发生改变时此方法会被调用。
d、onPostExecute(Result result),在主线程中执行,在异步任务执行之后,此方法会被调用,其中result参数是后台任务的返回值,即doInBackground的返回值。
除了上述方法以外,AsyncTask还提供了onCancelled()方法,它同样在主线程中执行,当异步任务被取消时,onCancelled()方法会被调用,这个时候onPostExecute不会被调用。
注意:
a、AsyncTask的类必须在主线程中加载;
b、AsyncTask的对象必须在主线程中创建;
c、execute方法必须在UI线程调用;
d、一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行的异常。
3、HandlerThread
HandlerThread继承Thread,它是一种可以使用Handler的Thread,它的实现是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就允许在HandlerThread中创建Handler了。
4、IntentService
IntentService是一种特殊的Service,它继承了Service并且它是一个抽象类,因此必须创建它的子类才能使用IntentService。