本文源代码基于 Android 7.0。
有两种不同的方式来注册系统服务:
- ServiceManager.addService()
- SystemServiceManager.startService()
这两种方式最终都是向 service manager 进程注册 Binder 服务,但是在功能上有区别,下面从代码角度来分析。
1. ServiceManager.addService()
以 InputManagerService 为例。
- 1.1 启动服务
/base/services/java/com/android/server/SystemServer.java
在 system server 启动时,会创建 InputManagerService 服务,并将其注册到 Service Manager 中。
private void startOtherServices() {
// ...
InputManagerService inputManager = null;
inputManager = new InputManagerService(context);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
// ...
}
- 1.2 ServierManager.addService()
/base/tools/layoutlib/bridge/src/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
采用了 getIServiceManager() 返回的是 ServiceManagerProxy 对象。
- 1.3 ServiceManagerNative
/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
// 由于obj为BpBinder,该方法默认返回null
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
这边返回的是 ServiceManagerProxy 对象,addService() 经过 IPC 最终到达 ServiceManagerNative 的 onTransaction():
case IServiceManager.ADD_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
boolean allowIsolated = data.readInt() != 0;
addService(name, service, allowIsolated);
return true;
}
最终进入 service manager 进程,具体可以参考:Framework篇 - ServiceManager 注册和获取服务
2. SystemServiceManager.startService()
通过这种方式启动的服务,有一个特点都是继承于 SystemService 类,比如 JobSchedulerService。
- 2.1 启动服务
/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
// ...
mSystemServiceManager.startService(JobSchedulerService.class);
// ...
}
- 2.1 JobSchedulerService
/base/services/core/java/com/android/server/job/JobSchedulerService.java
public final class JobSchedulerService extends com.android.server.SystemService
implements StateChangedListener, JobCompletedListener {
}
可以看到,它继承于 SystemService 类。
- 2.2 SystemServiceManager.startService()
/base/services/core/java/com/android/server/SystemServiceManager.java
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
// 采用反射
try {
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
}
return startService(serviceClass);
}
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
final T service;
try {
// 构造出Service对象
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
}
// 添加到ArrayList<SystemService>中
mServices.add(service);
try {
// 调用Service的onStart方法
// 看到这并没有看到服务是如何注册到ServiceManager, 其实是在 service 的 onStart() 中完成
service.onStart();
} catch (RuntimeException ex) {
}
return service;
} finally {
}
}
注意上面,有个 mService 对象,是一个 SystemService 的集合,两种注册服务的方式区别就在于它,后面会讲。
- 2.3 JobSchedulerService.onStart()
/base/services/core/java/com/android/server/job/JobSchedulerService.java
注册服务是在 onStart() 中,看看 JobSchedulerService 的 onStart():
@Override
public void onStart() {
publishLocalService(JobSchedulerInternal.class, new LocalService());
publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub);
}
- 2.4 SystemService.publishBinderService()
/base/services/core/java/com/android/server/SystemService.java
publishBinderService() 定义在 JobSchedulerService 的父类 SystemService 中:
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
// 最终还是调用了ServiceManager的addService函数来注册服务
// 通过这种方式启动的服务, 都是继承于SystemService类, 那么这种方式启动的服务有什么特殊之处吗? 答应就是startBootPhase的过程:
ServiceManager.addService(name, service, allowIsolated);
}
可以看到,最终还是调用了 ServiceManager.addService()。
3. 两种方式的区别
SystemServiceManager 中有一个 ServiceManager 的集合,每通过它注册一个服务,便会将该服务放到集合中。看看 SystemServiceManager 的 startBootPhase():
// 所有通过该方式注册的继承于SystemService的服务,都会被添加到mServices.
// 该方法会根据当前系统启动到不同的阶段, 则回调所有服务onBootPhase()方法
public void startBootPhase(final int phase) {
mCurrentPhase = phase;
try {
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
try {
service.onBootPhase(mCurrentPhase);
} catch (Exception ex) {
// ...
}
}
} finally {
}
}
系统开机启动过程,当执行到 system_server 进程时,将启动过程划分了几个阶段,定义在 SystemService.java 文件中:
/*
* Boot Phases
*/
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?
/**
* After receiving this boot phase, services can obtain lock settings data.
*/
public static final int PHASE_LOCK_SETTINGS_READY = 480;
/**
* After receiving this boot phase, services can safely call into core system services
* such as the PowerManager or PackageManager.
*/
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
/**
* After receiving this boot phase, services can broadcast Intents.
*/
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
/**
* After receiving this boot phase, services can start/bind to third party apps.
* Apps will be able to make Binder calls into services at this point.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
/**
* After receiving this boot phase, services can allow user interaction with the device.
* This phase occurs when boot has completed and the home application has started.
* System services may prefer to listen to this phase rather than registering a
* broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
*/
public static final int PHASE_BOOT_COMPLETED = 1000;
PHASE_BOOT_COMPLETED=1000,该阶段是发生在 Boot 完成和 home 应用启动完毕,对于系统服务更倾向于监听该阶段,而非监听广播 ACTION_BOOT_COMPLETED。