Service源码浅析一
Service源码浅析二
Service源码浅析三
Service源码浅析四
Service类的代码量比较少,内容没什么可说的。
Service是一个抽象类。

1. Start Service
@Nullable
public abstract ComponentName startService(Intent service);
start service其实调用的是Context的方法,Context的实现类是ContextWrapper,它的startService方法如下:
@Override
public @Nullable ComponentName startService(Intent service) {
return mBase.startService(service);
}
ContextWrapper使用代理模式,其中真正的实现类是mBase,mBase是ContextImpl的实例。
在ContextImpl中会依次调用 startService->startServiceCommon->ActivityManager.getService().startService
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
ActivityManager.getService方法如上,ActivityManager其实就是ActivityManagerService的客户端类。
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这里用到了Singleton类,它是一个单例的工具类,在咱们得代码中也可以使用,代码我也贴一下
public abstract class Singleton<T> {
@UnsupportedAppUsage
public Singleton() {
}
@UnsupportedAppUsage
private T mInstance;
protected abstract T create();
@UnsupportedAppUsage
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
通过IActivityManagerSingleton返回了IActivityManagerSingleton的Binder对象,猜测这里发生了进程通信,详细不深究了,后边看AMS的时候补上,咱们先顺流程。
接下来就进入了ActivityManagerService进程了,调用它的startService方法。
继续走到ActiveServices的startServiceLocked,ActiveServices是ActivityManagerService的辅助类。
顺着主线继续走,ActiveServices#startServiceLocked -> startServiceInnerLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
-> IApplicationThread#scheduleCreateService
走到这里有发生了一次进程通信,已经进入到对应进程里了,这里仍然疑点重重:
- 这里应该发生了进程创建;
-
如果是同一个进程怎么处理的;
细节留到后边再补,先顺着流程走,在这之前先补个简图,方便理解。
startService
ApplicationThread是ActivityThread的内部类,ActivityThread其实就是应用的进程入口,进程创建时会触发ActivityThread#main函数。
scheduleCreateService会向主线程的handler中发送创建服务的消息,最终调用handleCreateService,在此方法中,如果Application对象未创建,会创建Application对象并触发其onCreate方法。同时实例化Service并调用其onCreate方法。
onCreate方法执行之后咱们回到 ActiveServices#realStartServiceLocked,这里触发了IApplicationThread#scheduleCreateService之后,后边还触发了sendServiceArgsLocked,在这个方法中最终会触发r.app.getThread().scheduleServiceArgs,这里有一次进程间通信再次来到ApplicationThread。在ApplicationThread中会触发 Service#onStartCommand。
到这里Start Service流程基本结束了。
2. Bind Service
public abstract boolean bindService(@RequiresPermission @NonNull Intent service,
@NonNull ServiceConnection conn, int flags);
我们按照同样的方式继续分析bindService
首先来到 ContextImpl#bindServiceCommon,在这里会调用ActivityManager.getService().bindServiceInstance,这里发生了进程通信,进入AMS进程。
ActiveServices#bindServiceLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
在realStartServiceLocked方法中会触发thread.scheduleCreateService来创建Service实例。
Service onCreate执行之后接下来继续执行requestServiceBindingsLocked -> r.app.getThread().scheduleBindService,又是进程通信,同样的套路触发ApplicationThread#handleBindService,然后触发Service的onBind返回一个IBinder用于进程间通信。
接下来是AMS的publishService -> ActiveServices#publishServiceLocked,最终会触发IServiceConnection#connected回调方法,这里要刹一脚车了,这个IServiceConnection是个什么东西?
这就不得不回到起点了,bindService时会传入ServiceConnection,这个参数经过LoadedApk#getServiceDispatcher -> getServiceDispatcherCommon,在这个方法中会创建ServiceDispatcher,然后又会创建InnerConnection,这个就是我们要找的IServiceConnection
private static class InnerConnection extends IServiceConnection.Stub {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}
触发它的connected,最终会调用ServiceDispatcher#connected
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
在这三个分支中都会触发doConnected,最终会调用onServiceConnected回调方法,至此bindService流程结束了。
补充一点:这里mActivityThread就是主线程的Handler,可以得出onServiceConnected最终会运行在主线程。
3. Unbind Service
public abstract void unbindService(@NonNull ServiceConnection conn);
同样执行ContextImpl#unbindService方法
@Override
public void unbindService(ServiceConnection conn) {
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
getOuterContext(), conn);
try {
ActivityManager.getService().unbindService(sd);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
throw new RuntimeException("Not supported in system context");
}
}
这里的mPackageInfo就是LoadedApk实例。
AMS#unbindService -> ActiveServices#unbindServiceLocked -> removeConnectionLocked -> ActivityThread#scheduleUnbindService -> handleUnbindService -> Service#onUnbind -> AMS#unbindFinished -> ActiveServices#unbindFinishedLocked
回到ActiveServices#removeConnectionLocked -> removeConnectionLocked -> bringDownServiceIfNeededLocked -> bringDownServiceLocked -> ActivityThread#scheduleStopService -> Service#onDestroy
