[toc]
平台对外提供新接口的几种方式:
- 1、标准写法:同 AMS WMS 一样,在 system_server 中添加一个新的服务
- 缺点1,代码具有侵入性。同时代码出现问题会把SystemServer带崩,整个系统就崩了
- 缺点2,只能随系统rom升级
- 2、写一个AIDL接口的persistent系统App,内部写一个binder服务,加入到ServiceManager。
- 优点,能跟随系统启动而启动,并且进程死亡后自动重启。
- 缺点,不能使用app商店升级,只能随系统rom升级。
- 缺点,连续崩溃次数太多会导致系统上层重启
- 3、写一个HIDL接口的native进程的HWbinder服务
- 优点,能提供vendor进程域特有的数据(有些数据系统app不方便拿)
- 缺点,提供的是bin文件,同样不方便升级
- 4、写一个普通的系统app,内部写一个普通的 app service
- 优点,解耦程度最高,能够随时升级
- 缺点,需要自身维持进程永驻
- 5、其他:socket、contentprovider等等
以下内容讲述"标准写法"。
步骤简述
-
1、定义 aidl 接口,比如 ITestManager.aidl
-
2、创建服务类 比如 TestManagerService.java
-
继承抽象父类 SystemService 和 aidl接口 ITestManager.aidl
-
实现服务的相关功能
-
实现父类的 onStart() 方法
- onStart中调用 publishBinderService("TestService", mService);
- publishBinderService 函数为父类 SystemService 的方法。
- publishBinderService 方法内部会调用 ServiceManager.addService 添加 binder 服务
-
如有必要实现其他周期函数(这些周期函数会随启动阶段,系统状态而被调用)
-
-
3、SystemServer.java 中找个合适的位置,调用 SystemServiceManager.startService 方法:
-
mSystemServiceManager.startService(TestManagerService.class);
- startService 方法内部会把反射后得到的服务实例添加到数组 mServices ,用于systemserver遍历所有服务,分发生命周期事件。
- 并会调用TestManagerService服务的 onStart() 方法,最终调用 ServiceManager.addService 添加binder服务
-
-
4、创建App进程端的binder服务代理类,比如:TestManager.java
- TestManager.java 中获取binder服务代理,并实现各种代理接口
- 然后在 SystemServiceRegistry.java 中,调用registerService方法,把TestManager的实例注册到 SystemServiceRegistry
-
5、使用
- App端的代码可以像使用其他系统服务一样使用:
- TestManager testManager = context.getSystemService(SERVICE_NAME);
其他细节,需要处理隐藏类问题,系统接口问题等等。
按进程来看各部分代码
SystemServer 进程
-
SystemServer 相关函数中插入添加系统服务的代码------添加的系统服务处于 SystemServer 进程中
- frameworks/base/services/java/com/android/server/SystemServer.java
-
SystemServiceManager SystemServer 中添加服务调用的方法是 SystemServiceManager.startService(TestManagerService.class)
- SystemServiceManager 统一处理所有 service 的生命周期。SystemServer进程通过SystemServiceManager把系统状态事件分发到各个服务。SystemServiceManager遍历其数组对象mServices的所有的service,调用对应的周期函数。
- frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
-
SystemService 系统服务继承此类------抽象类---定义了生命周期函数
- frameworks/base/services/core/java/com/android/server/SystemService.java
App进程
-
SystemServiceRegistry.java
- framework.jar中的代码。创建binder服务代理实例,并注册到SystemServiceRegistry.java中。
- 这里是在静态代码中创建的实例,每个app启动时,都会把系统服务的代理实例预先注册到 SystemServiceRegistry。
- app进程通过 context.getSystemService 获取各种binder服务代理
- frameworks\base\core\java\android\app\SystemServiceRegistry.java
ServiceManager 进程
-
SystemServer 进程中调用 ServiceManager.addService() 函数,把binder服务添加到 ServiceManager 进程
- /frameworks/base/core/java/android/os/ServiceManager.java
- frameworks/native/cmds/servicemanager/ServiceManager.cpp
SystemServer进程中添加系统服务过程
- SystemServiceManager.startService(TestManagerService.class);
- SystemServiceManager.mServices.add(service);
- service.onStart(); // 调用TestManagerService.onStart();
- SystemService.publishBinderService("TestService", mService);
- ServiceManager.addService(name, service, allowIsolated, dumpPriority);
- SystemService.publishBinderService("TestService", mService);
//frameworks/base/services/java/com/android/server/SystemServer.java
//SystemServer.java 调用SystemServiceManager启动各种系统服务
mSystemServiceManager.startService(OemInfoManagerService.class);
// 反射获得实例后调用 startService(SystemService service) 方法
///frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void startService(@NonNull final SystemService service) {
// Register it.
// 用于统一处理各种service的生命周期函数
// 比如 SystemServiceManager.startBootPhase 方法中 遍历 mServices 中的服务,调用每个服务的 onBootPhase 方法
mServices.add(service); // mServices 是个数组 ArrayList<SystemService>
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();//===调用对应服务的onStart方法==========!!!!
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
//TestManagerService.java
@Override
public void onStart() {
publishBinderService("TestService", mService);
}
//com.android.server.SystemService
///frameworks/base/services/core/java/com/android/server/SystemService.java
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated, int dumpPriority) {
//添加到 ServiceManager
ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
context.getSystemService(Context.XXXX) 功能的的实现
以WMS为例:
//frameworks\base\core\java\android\app\SystemServiceRegistry.java
// SystemServiceRegistry 注册管理器
// 在静态代码块中注册管理器, 所以每个App进程都会有一份
static {
registerService(Context.WINDOW_SERVICE, WindowManager.class,new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx);
}
}
);
}
// Context 中获取服务管理器
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
// frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
if (vmIncorrectContextUseEnabled()) {
// We may override this API from outer context.
final boolean isUiContext = isUiContext() || isOuterUiContext();
// Check incorrect Context usage.
if (isUiComponent(name) && !isUiContext) {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
final String message = "Visual services, such as WindowManager, WallpaperService "
+ "or LayoutInflater should be accessed from Activity or other visual "
+ "Context. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
+ "the configuration and visual bounds of an area on screen.";
final Exception exception = new IllegalAccessException(errorMessage);
StrictMode.onIncorrectContextUsed(message, exception);
Log.e(TAG, errorMessage + " " + message, exception);
}
}
// 调用的 SystemServiceRegistry.getSystemService
return SystemServiceRegistry.getSystemService(this, name);
}
// 最终调用
SystemServiceRegistry.getSystemService(this, name);