源码分析Service和IntentService的区别
概念:Service是长时间运行在后台而不用提供用户界面的应用组件,可由其他组件启动,即使用户切换到其他应用程序,Service 仍然在后台继续运行。
特征:Service分两种工作状态
Context.startService()
Service一旦启动,就会在后台无限期的运行,生命周期独立于启动它的组件,即使启动它的组件已经销毁了也不受任何影响。任务执行完成之后可以通过调用stopSelf()来停止服务,或者通过其他应用组件调用stopService来停止服务。这种方式一般用于在后台执行任务,而不需要返回结果给启动组件。
Context.bindService()
绑定方式,用bindservice连接。多个组件可以绑定到同一个服务上,如果只有一个组件绑定服务,当绑定的组件被销毁时,服务也就会停止了。如果是多个组件绑定到一个服务上,当绑定到该服务的所有组件都被销毁时,服务才会停止。且Service还有一个特性,多次绑定同一个Service时,Service的onBind方法只会执行一次,除非Service被终止了。绑定服务的方式通常用于组件和服务之间相互通信。
启动方式不同,生命周期不同:
启动服务
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,继承了Service并且是一个抽象类,可用于执行后台耗时任务,任务执行完后,IntentService 会自动停止,不需要手动停止。
特征:
IntentService会创建独立的工作线程来处理任务请求。
请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service。
可以多次启动 IntentService执行任务,而每一个耗时操作会以工作队列的方式在IntentService 的onHandleIntent 回调方法中执行,且多个任务串行执行。
比Service拥有更高优先级,适合高优先级的后台任务,且不容易被系统杀死。
Intentservice源码解读
首先,IntentService是个抽象类,并且继承Service,拥有父类Service的特性。
然后,是IntentService的onCreate方法,可以看到其创建了一个工作线程,新建了一个HandlerThread,并获取HandlerThread的Looper初始化了ServiceHandler。即发送到Handler中处理的消息运行在这个HandlerThread线程中。
其内部的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中处理耗时任务。