一、源代码版本
源代码版本:Source for Android 30 (Android10.0+(R))
Service有两种工作状态,一种是启动状态,主要用于执行后台计算;另一种是绑定状态,主要用于和其他人组件和Service交互。需要注意的是,Service的这两种状态是可以共存的,即Service即可以处于启动状态又可以处于绑定状态。
二、Service的启动状态
首先,我们编写一个ServiceDemo,该工程下有一个Activity即MainActivity,和一个Service即MyService,还有一个布局文件activity_main.xml。
在MainActivity中,通过ContextWrapper#startService()方法可以启动一个Service,如下图所示。
我们进入ContextWrapper类的startService()方法,如下图所示,在startService()方法中,mBase的类型是Context的子类ContextImpl。从ContextWrapper类的实现可以看出,其大部分操作都是通过mBase来实现的,在设计模式中,这是一种桥接模式。
接下来,进入Context类的startService()方法,如下图所示。
可以看出在Context类中,定义了抽象的startService()方法,而mBase的类型是Context的子类ContextImpl,ContexImpl类继承了Context类并重写了startService()方法。
可以看出ContextImpl#startService()方法回调了ContextImpl#startServiceCommon()方法,进入startServiceCommon()方法,如下图所示。
startServiceCommon()方法通过ActivityManager.getService()这个对象来启动一个服务,这个对象我们在Activity的工作过程中也遇到过,其实质是AMS(ActivityManagerService)。我们通过ActivityManager.getService()方法跳转到AcitvityManager类,如下图所示。
可以看出,ActivityManager#getService()方法返回的是IActivityManagerSingleton对象的get()方法,该返回值是一个IBinder对象,跳转查看。
可以看到IActivityManagerSingleton对象的类型是IActivityManager,在IActivityManager类中,Singleton是一个单例的封装类,第一次调用它的get()方法时,它会通过create()方法来初始化IBinder对象,在后续的调用中则直接返回之前创建的对象,而通过create()方法,getService()获取了IActivityManager.Stub接口(AIDL接口)。综上所示,ActivityManager.getService()方法实际上调用到了ActivityManagerService类的startService()方法,来获取一个AMS实例,并将远程对象IBinder传递给该实例。
接下来,进入ActivityManagerService类中的startService()方法查看,如下图所示。
在ActivityManagerService#startService()方法中,通过mServices.startServiceLocked()方法来完成后续的启动过程,mService对象的类型是ActivityServices,如下图所示。(ActivityServices是一个辅助AMS进行Service管理的类,包括Service的启动、绑定和停止等。)
接下来,我们进入ActivityServices#startServiceLocked()方法(9个参数),然后回调到ActivityServices#startServiceLocled()方法(10个参数)
可以看到startServiceLocked()方法跳转到了ActivityServices#startServiceInnerLocked()对象,我们跳转查看。
可以看到在startServiceInnerLocked()方法中又调用到ActivityService#bringUpServiceLocked()方法,跳转查看。
在bringUpServiceLocked()方法中又调用了ActivityService#realStartServiceLocked()方法,如下图所示。
在realStartServiceLocked()方法中,首先通过app.thread的scheduleCreateService()方法来创建Service对象,然后再通过ActivityServices#sendServiceArgsLocked()方法来调用Service的其他方法。由于app.thread对象是IApplicationThread类型,调用它的scheduleCreateService()方法之后,我们进入ActivityThread类的scheduleCreateService()方法,如下图所示。
ActivityThread#scheduleCreateService()方法通过发送CREATE_SERVICE消息给Handler H,H接收到这个消息并通过ActivityThread的handleCreateService()方法来完成,如下图所示。
我们跳转到ActivityThread#handleCreateService()方法,如下图所示。
在handleCreateService()方法中,首先,创建ContextImpl对象来建立与activity的联系。其次,创建Application对象。然后,通过类加载器创建Service实例。最后,调用Service的onCreate()方法来启动Service。至此,进入Service类的onCreate()方法来启动Service。
三、Service的绑定状态
首先,我们编写一个ServiceDemo,该工程下有一个Activity即MainActivity,和一个Service即MyService,还有一个布局文件activity_main.xml。
在MainActivity中,通过ContextWrapper#bindService()方法可以绑定一个Service,如下图所示。
我们进入ContextWrapper类的bindService()方法,如下图所示,在bindService()方法中,mBase的类型是Context的子类ContextImpl。从ContextWrapper类的实现可以看出,其大部分操作都是通过mBase来实现的,在设计模式中,这是一种桥接模式。
接下来,进入Context类的bindService()方法,如下图所示。
可以看出在Context类中,定义了抽象的bindService()方法,而mBase的类型是Context的子类ContextImpl,ContexImpl类继承了Context类并重写了bindService()方法。
可以看出ContextImpl#bindService()方法回调了ContextImpl#bindServiceCommon()方法,进入bindServiceCommon()方法,如下图所示。
首先,ContextImpl#bindServiceCommon()方法将ServiceConnection对象转化为ServiceDispatcher对象,因为服务的绑定可能会跨进程,因此ServiceConnection对象必须借助于IBinder才能让远程服务回调自己的方法。我们跳转到LoadedApk#getServiceDispatcher()方法,该方法又回调LoadedApk类的getServiceDispatcherComon()方法,在getServiceDispatcherComon()方法中,mService是一个ArrayMap,它存储一个应用当前活动的ServiceConnection和ServiceDispatcher的映射关系,系统首先会查找是否存在相同的ServiceConnection,如果不存在就会重新创建一个ServiceDispatcher对象并将其存储在mServices中,其中映射关系的key是ServiceConnection,value是ServiceDispatcher,在ServiceDispatcher的内部又保存了ServiceConnection和ServiceDispatcher,如下图所示。
然后,ContextImpl#bindServiceCommon()方法通过ActivityManager.getService()这个对象来绑定一个服务,其实质是AMS(ActivityManagerService),我们通过ActivityManager.getService()方法跳转到AcitvityManager类,如下图所示。
可以看出,ActivityManager#getService()方法返回的是IActivityManagerSingleton对象的get()方法,该返回值是一个IBinder对象,跳转查看。
可以看到IActivityManagerSingleton对象的类型是IActivityManager,在IActivityManager类中,Singleton是一个单例的封装类,第一次调用它的get()方法时,它会通过create()方法来初始化IBinder对象,在后续的调用中则直接返回之前创建的对象,而通过create()方法,getService()获取了IActivityManager.Stub接口(AIDL接口)。综上所示,ActivityManager.getService()方法实际上调用到了ActivityManagerService类的bindIsolatedService()方法,来获取一个AMS实例,并将远程对象IBinder传递给该实例。
接下来,进入ActivityManagerService类中的bindIsolatedService()方法查看,如下图所示。
在ActivityManagerService#bindIsolatedService()方法中,通过mServices.bindServiceLocked()方法来完成后续的绑定过程,mService对象的类型是ActivityServices。(ActivityServices是一个辅助AMS进行Service管理的类,包括Service的启动、绑定和停止等。)接下来,我们进入ActivtityServices#bindServiceLocked()方法(共294行),如下图所示。
可以看到bindServiceLocked()方法跳转到了ActivityServices#bringUpServiceLocked()方法,以及ActivityServices#requestServiceBindingLocked()方法。
首先,我们跳转查看ActivityServices#bringUpServiceLocked()方法。
在bringUpServiceLocked()方法中又调用了ActivityServices#realStartServiceLocked()方法,如下图所示。
在realStartServiceLocked()方法中,首先通过app.thread的scheduleCreateService()方法来创建Service对象,然后再通过ActivityServices#sendServiceArgsLocked()方法来调用Service的其他方法。由于app.thread对象是IApplicationThread类型,调用它的scheduleCreateService()方法之后,我们进入ActivityThread类的scheduleCreateService()方法,如下图所示。
ActivityThread#scheduleCreateService()方法通过发送CREATE_SERVICE消息给Handler H,H接收到这个消息并通过ActivityThread的handleCreateService()方法来完成,如下图所示。
我们跳转到ActivityThread#handleCreateService()方法,如下图所示。
在handleCreateService()方法中,首先,创建ContextImpl对象来建立与activity的联系。其次,创建Application对象。然后,通过类加载器创建Service实例。最后,调用Service的onCreate()方法来启动Service。
然后,我们跳转查看ActivityServices#requestServiceBindingLocked()方法。
在requestServiceBindingLocked()方法中,调用了app.thread.scheduleBinderService,而app.thread实际上是IApplicationThread类型,调用它的scheduleBindService()方法后,我们进入了ActivityThread类,如下图所示。
ActivityThread#scheduleBindService()方法通过发送BIND_SERVICE消息给Handler H,H接收到这个消息并通过ActivityThread的handleBindService()方法来完成,如下图所示。
我们跳转到ActivityThread的handleBindService()方法中,如下图所示。
在handleBindService()方法中,如果当前Service未被绑定,则调用Service#onBind()方法来绑定Service。由于在Service中,当多次绑定同一个Service时,Service的onBind()方法只执行一次,除非Service被终止了,该部分功能通过调用AMS#publishService()方法来实现。如果Service的onBind()方法执行后,系统需要通知客户端已经成功连接Service了,该部分功能通过调用AMS#serviceDoneExecuting()方法来实现。