如何实现一个 System Services?,超详细
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("StartDisplayManager");//开启 DisplayManagerServicemDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);t.traceEnd();}private void startOtherServices(@NonNull TimingsTraceAndSlog t) {//通知服务系统启动完成 t.traceBegin("MakeDisplayManagerServiceReady");try {// TODO: use boot phase and communicate these flags some other waymDisplayManagerService.systemReady(safeMode, mOnlyCore);} catch (Throwable e) {reportWtf("making Display Manager Service ready", e);}t.traceEnd();}
看完 DisplayManagerService 是怎么写的,不妨模仿写个。 所谓看着代码,感觉还是挺简单的,实际操作起来,各种编译报错……
如何写个 System Service
先上图:
1.编写 AIDL 文件
新建 frameworks/base/core/java/android/hardware/wuxiaolong/IWuXiaolongManager.aidl,内容如下:
package android.hardware.wuxiaolong;/** @hide */interface IWuXiaolongManager {
String getName();}
2.Context 定义变量
在 Context 里定义一个代表 wuxiaolong 服务的字符串 frameworks/base/core/java/android/content/Context.java
public static final String WUXIAOLONG_SERVICE = "wuxiaolong";
3.编写系统服务
frameworks/base/services/core/java/com/android/server/wuxiaolong/WuXiaolongManagerService.java
package com.android.server.wuxiaolong;
import android.content.Context;import android.hardware.wuxiaolong.IWuXiaolongManager;
public class WuXiaolongManagerService extends IWuXiaolongManager.Stub {private final Context mContext;
public WuXiaolongManagerService(Context context) {super();mContext = context;}
@Overridepublic String getName() {String name = "WuXiaolong..";return name;}}
4.注册系统服务
frameworks/base/services/java/com/android/server/SystemServer.java
import com.android.server.wuxiaolong.WuXiaolongManagerService;private void startOtherServices() {// 部分代码省略...try {android.util.Log.d("wxl","SystemServer WuXiaolongManagerService");ServiceManager.addService(Context.WUXIAOLONG_SERVICE, new WuXiaolongManagerService(context));} catch (Throwable e) {reportWtf("starting WuXiaolongManagerService", e);}// 部分代码省略...}
5.编写 Manager 类
frameworks/base/core/java/android/hardware/wuxiaolong/WuXiaolongManager.java
package android.hardware.wuxiaolong;
import android.os.IBinder;import android.os.ServiceManager;import android.hardware.wuxiaolong.IWuXiaolongManager;import android.content.Context;import android.os.RemoteException;import android.compat.annotation.UnsupportedAppUsage;import android.annotation.Nullable;import android.os.ServiceManag
er.ServiceNotFoundException;import android.annotation.SystemService;
@SystemService(Context.WUXIAOLONG_SERVICE)public class WuXiaolongManager {private static WuXiaolongManager sInstance;private final IWuXiaolongManager mService;private Context mContext;
/**
@hide*/public WuXiaolongManager(IWuXiaolongManager iWuXiaolongManager) {mService = iWuXiaolongManager;}
/**
Gets an instance of the WuXiaolong manager.
@return The WuXiaolong manager instance.
@hide*/@UnsupportedAppUsagepublic static WuXiaolongManager getInstance() {android.util.Log.d("wxl", "WuXiaolongManager getInstance");synchronized (WuXiaolongManager.class) {if (sInstance == null) {
try {IBinder b = ServiceManager.getServiceOrThrow(Context.WUXIAOLONG_SERVICE);sInstance = new WuXiaolongManager(IWuXiaolongManager.Stub.asInterface(ServiceManager.getServiceOrThrow(Context.WUXIAOLONG_SERVICE)));} catch (ServiceNotFoundException e) {throw new IllegalStateException(e);}
}return sInstance;}}
@Nullablepublic String getName() {android.util.Log.d("wxl", "WuXiaolongManager getName");try {return mService.getName();} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}}
6.注册 Manager
frameworks/base/core/java/android/app/SystemServiceRegistry.java
import android.hardware.wuxiaolong.WuXiaolongManager;static {registerService(Context.WUXIAOLONG_SERVICE, WuXiaolongManager.class,new CachedServiceFetcher<WuXiaolongManager>() {@Overridepublic WuXiaolongManager createService(ContextImpl ctx)throws ServiceNotFoundException {android.util.Log.d("wxl","SystemServiceRegistry registerService");return WuXiaolongManager.getInstance();}});}
7.应用调用
WuXiaolongManager mWuXiaolongManager = (WuXiaolongManager)mContext.getSystemService(Context.WUXIAOLONG_SERVICE);android.util.Log.d("wxl","Name="+ mWuXiaolongManager.getName());
8.解决报错
编译报错
报错 1:
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)to the new methods, etc. shown in the above diff.
You can update current.txt and/or removed.txt by executing the following command:make api-stubs-docs-non-updatable-update-current-api
To submit the revised current.txt to the main Android repository,you will need approval.
需要执行 make update-api,更新接口,会多出来:
frameworks/base/api/current.txt
diff --git a/api/current.txt b/api/current.txtindex 6b1a96c..0779378 100755--- a/api/current.txt+++ b/api/current.txt@@ -10256,6 +10256,7 @@ package android.content {field public static final String WIFI_RTT_RANGING_SERVICE = "wifirtt";field public static final String WIFI_SERVICE = "wifi";field public static final String WINDOW_SERVICE = "window";
field public static final String WUXIAOLONG_SERVICE = "wuxiaolong";}
public class ContextWrapper extends android.content.Context {@@ -18318,6 +18319,14 @@ package android.hardware.usb {
}
+package android.hardware.wuxiaolong {+
public class WuXiaolongManager {
method @Nullable public String getName();
}
+}+package android.icu.lang {
frameworks/base/non-updatable-api/current.txt
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txtindex adf1bb5..e738c02 100755--- a/non-updatable-api/current.txt+++ b/non-updatable-api/current.txt@@ -10256,6 +10256,7 @@ package android.content {field public static final String WIFI_RTT_RANGING_SERVICE = "wifirtt";field public static final String WIFI_SERVICE = "wifi";field public static final String WINDOW_SERVICE = "window";
field public static final String WUXIAOLONG_SERVICE = "wuxiaolong";}
public class ContextWrapper extends android.content.Context {@@ -18318,6 +18319,14 @@ package android.hardware.usb {
}
+package android.hardware.wuxiaolong {+
public class WuXiaolongManager {
method @Nullable public String getName();
}
+}+package android.icu.lang {
报错 2:
[0mManagers must always be obtained from Context; no direct constructors [ManagerConstructor]
编写 Manager 类需写成单例。
报错 3:
Missing nullability on method getName
return [MissingNullability]
getName 方法加上@Nullable
注解。
运行报错
04-08 15:41:38.798 297 297 E SELinux : avc: denied { find } for pid=12717 uid=1000 name=wuxiaolong scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=104-08 15:41:38.802 12717 12758 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: PowerManagerService04-08 15:41:38.802 12717 12758 E AndroidRuntime: java.lang.IllegalStateException: android.os.ServiceManager27.createService(SystemServiceRegistry.java:497)04-08 15:41:38.802 12717 12758 E AndroidRuntime: at android.app.SystemServiceRegistryCachedServiceFetcher.getService(SystemServiceRegistry.java:1760)04-08 15:41:38.802 12717 12758 E AndroidRuntime: at android.app.SystemServiceRegistry.getSystemService(SystemServiceRegistry.java:1440)04-08 15:41:38.802 12717 12758 E AndroidRuntime: at android.app.ContextImpl.getSystemService(ContextImpl.java:1921)04-08 15:41:38.802 12717 12758 E AndroidRuntime: at com.android.server.display.DisplayPowerController.updatePowerState(DisplayPowerController.java:1191)04-08 15:41:38.802 12717 12758 E AndroidRuntime: at com.android.server.display.DisplayPowerController.accessDisplayControllerHandler.handleMessage(DisplayPowerController.java:2074)
评论