HandlerThread继承了Thread,它是一种可以使用Handler的Thread,它的实现也很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就循序在HandlerThread中创建Handler了,HandlerThread的run方法如下所示:
从 HanldeThread的实现来看,它和普通的Thread有显著的不同之处,普通Thread主要用于在run方法中执行一个耗时任务,而HandlerThread在内部创建了消息队列,外界需要通过Handler的消息方式来通知HandlerThread执行一个具体的任务。HandlerThread是一个很有用的类,它在Android中的一个具体的使用场景是IntentService,由于HandlerThread的run方法是一个无限循环,因此当明确不需要再使用HandlerThread时,可以通过它的quit或者quitSafely方法来终止线程的执行。
当IntentService被第一次启动时,它的onCreate方法会被调用,onCreate方法会创建一个HandlerThread,然后使用它的Looper来构造一个Handler对象mServiceHandler,这样通过mServiceHandler发送的消息最终都会在HandlerThread中执行,从这个角度看,IntentService也可以用来执行后台任务,每次启动IntentService,它的onStartCommand方法就会调用一次,IntentService在onStratCommand中处理每个后台任务的intent,下面看一下onStartCommand方法是如何处理外界的intent的,onStartCommand调用了onStart,onStart方法的实现如下:
可以看到,IntentService仅仅是通过mServiceHandler发送了一个消息,这个消息会在HandlerThread中被处理,mServiceHandler收到消息后,会将Intent对象传递给onHandlerIntent方法去处理,注意这个Intent对象的内容和外界的startService(intent)中的intent的内容是完全一直的,通过这个intent对象即可解析出外界启动IntentService时所传递的参数,通过这些参数就可以区分具体的后台任务,这样在onHandlerIntent方法中就可以对不同的后台任务做处理了,当onHandlerIntent方法执行结束后,IntentService会通过stopSelf(int startId)方法来尝试停止服务,这里之所以采用stopSelf(int startId)而不是stopSelf()来停止服务,那是因为stopSelf()会立刻停止服务,而这个时候可能还要其他消息未处理,stopSelf(int startId)则会等待所有的消息都处理完毕后才会终止服务,一般来说,stopSelf(int startId)在尝试停止服务之前会判断最近启动服务的次数是否和startId相等,如果相等就立刻停止服务,不相等则不停止服务,这个策略可以从AMS的stopServiceToker方法的实现中找到依据,ServiceHandler的实现如下所示:
IntentService的onHandlerIntent方法是一个抽象方法,它需要我们在子类中实现,它的作用是从Intent参数中区分具体的任务并执行这些任务,如果目前只存在一个后台任务,那么onHandlerIntent方法执行完这个任务后,stopSelf(int startId)就会直接停止服务,如果目前存在多个后台任务,那么当onHandlerIntent方法执行完最后一个任务时,stopSelf(int stratId)才会直接停止服务,另外,由于每执行一个后台任务就必须启动一次IntentService,而IntentService内部则通过消息的方式向HandlerThread请求执行任务,Handelr中的Looper是顺序处理消息的,这就意味着IntentService也是顺序执行后台任务的,当有多个后台任务同时存在时,这些后台任务会按照外界发起的顺序排队执行的
网友评论