Android线程(二) HandlerThread&IntentService

HandlerThread继承了Thread,它是一种可以使用Handler的Thread,它的实现也很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就循序在HandlerThread中创建Handler了,HandlerThread的run方法如下所示:

8656692-15a3a861e52be43d.png

从 HanldeThread的实现来看,它和普通的Thread有显著的不同之处,普通Thread主要用于在run方法中执行一个耗时任务,而HandlerThread在内部创建了消息队列,外界需要通过Handler的消息方式来通知HandlerThread执行一个具体的任务。HandlerThread是一个很有用的类,它在Android中的一个具体的使用场景是IntentService,由于HandlerThread的run方法是一个无限循环,因此当明确不需要再使用HandlerThread时,可以通过它的quit或者quitSafely方法来终止线程的执行。

8656692-0f4543024a0bb0f8.png

当IntentService被第一次启动时,它的onCreate方法会被调用,onCreate方法会创建一个HandlerThread,然后使用它的Looper来构造一个Handler对象mServiceHandler,这样通过mServiceHandler发送的消息最终都会在HandlerThread中执行,从这个角度看,IntentService也可以用来执行后台任务,每次启动IntentService,它的onStartCommand方法就会调用一次,IntentService在onStratCommand中处理每个后台任务的intent,下面看一下onStartCommand方法是如何处理外界的intent的,onStartCommand调用了onStart,onStart方法的实现如下:

8656692-762b4c7ec642dd29.png

可以看到,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的实现如下所示:

8656692-5976bacd79087f70.png

IntentService的onHandlerIntent方法是一个抽象方法,它需要我们在子类中实现,它的作用是从Intent参数中区分具体的任务并执行这些任务,如果目前只存在一个后台任务,那么onHandlerIntent方法执行完这个任务后,stopSelf(int startId)就会直接停止服务,如果目前存在多个后台任务,那么当onHandlerIntent方法执行完最后一个任务时,stopSelf(int stratId)才会直接停止服务,另外,由于每执行一个后台任务就必须启动一次IntentService,而IntentService内部则通过消息的方式向HandlerThread请求执行任务,Handelr中的Looper是顺序处理消息的,这就意味着IntentService也是顺序执行后台任务的,当有多个后台任务同时存在时,这些后台任务会按照外界发起的顺序排队执行的

8656692-9d4cb27aedf2624d.png
8656692-827032f71dbddaa6.png

猜你喜欢

转载自blog.csdn.net/weixin_33698043/article/details/87218681