Service&Thread$IntentService$HandlerThread

35 阅读2分钟

Service

Service常用于执行后台任务。

虽然说用于执行后台任务,但是需要我们注意的是,Service也是执行在主线程上的(Binder例外),因此需要执行耗时任务时,还是需要避免在主线程上直接执行,而是要手动将耗时任务放入子线程中。

Service & Thread

那么既然都是执行后台任务,和Thread相比,有什么区别呢?

Service是安卓中的四大组件之一,在安卓开发中会有其独特的优势:

(1)Service可以与Activity关联/绑定,在这种情况下,Service是可以具有和所绑定组件一样的生命周期的

(2)Service的机制有点类似于单例,也就是我们常说的多次startService或者bindService,onCreate只会回调一次,而onStartCommand/onBind则会回调多次

(3)可以通过Service.class或者ServiceConnection来找到已经start/bind的Service;而Thread一旦失去引用,是无法再找回引用的;

IntentService

那么当我们确定我们的Service是用于执行耗时任务、需要在子线程上执行时,就可以使用IntentService代替Service。

若使用IntentService,则我们只需要重写handleIntent方法,将耗时任务实现在这里即可,如:

class TestIntentService: IntentService("TestIntentService") {
    override fun onHandleIntent(intent: Intent?) {
        // do busy job
    }
}

IntentService 实现上是 { Service + HandlerThread }的一个封装

image.png

image.png

image.png

注意这里用了非静态的内部类,如果不稍做处理,非常容易发生内存泄漏。但是当然这里是做了处理的:

  1. service任务执行完之后,会调用stopSelf
  2. Service回调onDestroy的时候,会让lopper直接退出,这样所有的消息就会被移除了

HandlerThread

HandlerThread本质则是Thread+Handler

继承Thread,内部封装了Handler和Lopper,并且启动了Lopper循环。

我们可以通过HandlerThread.getHandler()快速创建和获取一个Handler

然后在需要向这个子线程发送消息的时候,可以使用ThreadHandler的lopper来初始化创建Handler,再通过这个Handler发送消息。这样下来,消息就会传到HandlerThread的线程上去处理。