vlambda博客
学习文章列表

源码分析Service和IntentService的区别



概念:Service是长时间运行在后台而不用提供用户界面的应用组件,可由其他组件启动,即使用户切换到其他应用程序,Service 仍然在后台继续运行。


特征:Service分两种工作状态


  • Context.startService()


    Service一旦启动,就会在后台无限期的运行,生命周期独立于启动它的组件,即使启动它的组件已经销毁了也不受任何影响。任务执行完成之后可以通过调用stopSelf()来停止服务,或者通过其他应用组件调用stopService来停止服务。这种方式一般用于在后台执行任务,而不需要返回结果给启动组件。


  • Context.bindService()


    绑定方式,用bindservice连接。多个组件可以绑定到同一个服务上,如果只有一个组件绑定服务,当绑定的组件被销毁时,服务也就会停止了。如果是多个组件绑定到一个服务上,当绑定到该服务的所有组件都被销毁时,服务才会停止。且Service还有一个特性,多次绑定同一个Service时,Service的onBind方法只会执行一次,除非Service被终止了。绑定服务的方式通常用于组件和服务之间相互通信。


启动方式不同,生命周期不同:


源码分析Service和IntentService的区别


启动服务

startService执行的生命周期:onCreate() —> onStartCommand() —> onDestroy()

1)启动服务/startService()

    单次:onCreate() —> onStartCommand()

    多次:onCreate() —> onStartCommand() —> onStartCommand() ……

    注意:多次启动服务onCreate()只会执行一次,onStartCommand()会执行多次;

2)停止服务/stopService()

    onDestroy()


绑定服务
bindService执行的生命周期:
onCreate() —> onBind() —> onUnbind() —> onDestroy()

 1)绑定服务/bindService()

    onCreate() —> onBind()

2)解绑服务/unbindService()

    onUnbind() —> onDestroy()


先启动后绑定服务
先startService后bindService的生命周期:
onCreate() —> onStartCommand() —> onBind() —> onUnbind() —> onDestroy()

1)启动绑定服务/startService()、bindService()

    onCreate() —> onStartCommand() —> onBind()

2)停止解绑服务/stopService()、unbindService()

    onUnbind() —> onDestroy()


先绑定后启动服务
先bindService后startService的生命周期:
onCreate() —> onBind() —> onStartCommand() —> onUnbind() —> onDestroy()

 1)绑定启动服务/bindService()、startService()

    onCreate() —> onBind() —> onStartCommand()

2)解绑停止服务/unbindService()、stopService()

    onUnbind() —> onDestroy()


先解绑再绑定服务
1)解绑再绑定服务/
unbindService()、bindService()
    onUnbind(ture) —> onRebind()


以上两种方式可以共存,即startService和bindService都可以执行多次,Service还是那一个实例。


线程
Service并不会新开启线程执行,其onCreate等回调方法都是执行在主线程中的。不建议在Service中编写耗时的操作逻辑,容易引起ANR。(10s超时)



源码分析Service和IntentService的区别


概念:一种特殊的Service,继承了Service并且是一个抽象类,可用于执行后台耗时任务,任务执行完后,IntentService 会自动停止,不需要手动停止。


特征:

  • IntentService会创建独立的工作线程来处理任务请求。

  • 请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service。

  • 可以多次启动 IntentService执行任务,而每一个耗时操作会以工作队列的方式在IntentService 的onHandleIntent 回调方法中执行,且多个任务串行执行。

  • 比Service拥有更高优先级,适合高优先级的后台任务,且不容易被系统杀死。


Intentservice源码解读

首先,IntentService是个抽象类,并且继承Service,拥有父类Service的特性。


源码分析Service和IntentService的区别


然后,是IntentService的onCreate方法,可以看到其创建了一个工作线程,新建了一个HandlerThread,并获取HandlerThread的Looper初始化了ServiceHandler。即发送到Handler中处理的消息运行在这个HandlerThread线程中。


源码分析Service和IntentService的区别


其内部的ServiceHandler即通过传入线程的Looper创建Handler,且执行完onHandleIntent任务后调用stopSelf关闭自己。



接下来,Service的生命周期onStart,其中将传进来的intent封装进Message并通过handler发送到工作线程处理。这个intent就是我们启动Service传进来的。

Intent intent = new Intent(Content,MyService.class);

intent.putExtra("key","value");

Content.startService(intent);

在Service的源码中,startService会调用onStartCommand回调,并把intent参数传给后者,而如下IntentService源码中显示,其又回调了onStart方法,又将intent参数传给了onStart,所以onStart方法中通过mServiceHandler发送的intent消息即是用户startService带的消息。



最后,由于用户继承IntentService,实现onHandleIntent方法,而onHandleIntent又接受了intent参数,并在开始的HandlerThread中处理耗时任务。