查看 SystemServer.java 的 run() 方法,可以看到两种系统服务的注册方式,分别是:
但是,同样是系统服务,为什么他们的注册方式不同呢?下面我们带着疑问来看一下这个问题。
举例:
inputManager = new InputManagerService(context);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
ServiceManager.java
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
ServiceManager.java
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
实际上是通过单例模式来获取 service manager,得到的是一个 ServiceManagerProxy 对象
ServiceManager.java
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
由此知,这里实际上是通过 mRemote 把 ADD_SERVICE_TRANSACTION 信息发送给 ServiceManager
举例:
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
SystemServiceManager.java
public T startService(Class serviceClass) {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
// 构建 service
...
final T service;
try {
Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (...) {
...
}
// 把 service 加入到 SystemServiceManager 对象的成员变量 mServices 中
mServices.add(service);
// Start it.
try {
service.onStart();
} catch (RuntimeException ex) {
}
return service;
}
总结一下,其主要做了三件事情:
下面我们来看看 service.onStart() 中做了什么,以 DisplayManagerService 为例:
DisplayManagerService.java
@Override
public void onStart() {
// 因 service 而异
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
// 主要动作
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);
publishLocalService(DisplayManagerInternal.class, new LocalService());
}
SystemService.java
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
可以看到其竟然像方式一一样,执行了 ServiceManager.addService,那么方式一和方式二还有什么不同呢?对比发现:
查找 mServices,可以发现其的作用:
SystemServiceManager.java
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
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) {
...
}
}
}
可以发现 SystemServiceManager 会回调 mServices 中注册 service 的 onBootPhase() 方法
方式一:ServiceManager.addService
方式二:SystemServiceManager.startService