当前位置:   article > 正文

Framework层添加SystemService和Manager的超详细步骤_framework添加新service

framework添加新service

本文适用于Android 12中增加系统服务。

目录

1.总体步骤

2、详细步骤

2.1 创建AIDL文件

2.2 报错修改

2.2.1 AIDL文件自动生成的Java文件报错

2.2.2 AIDL文件Observer/Callback/Listener命名报错修改

2.2.3 注册方法报错

2.2.4 避免使用枚举类enum

2.2.5 Callback如何让APP访问到

3. Context中定义service name

4. 编写SystemService

5. 在SystemServer类中注册新增的系统服务

6. 编写系统Manager类

7. 注册系统Manager类

8. 应用调用


1.总体步骤


2、详细步骤

2.1 创建AIDL文件

在framework/base/core/java/android/app下创建AIDL文件,如果业务比较复杂,可以创建模块文件夹。代码示例如下:

framework/base/core/java/android/app/devicemanager/IDeviceManager.aidl

  1. //framework/base/core/java/android/app/devicemanager/IDeviceManager.aidl
  2. package android.app.devicemanager;
  3. import android.app.devicemanager.DeviceEntity;
  4. import android.app.devicemanager.IDeviceObserver;
  5. interface IDeviceManager {
  6. int bindDivice(int deviceId);
  7. DeviceEntity getDeviceEntity(int deviceId);
  8. void registerDeviceObserver(in IDeviceObserver observer);
  9. void unregisterDeviceObserver(in IDeviceObserver observer);
  10. }

framework/base/core/java/android/app/devicemanager/IDiviceObserver.aidl

  1. //framework/base/core/java/android/app/devicemanager/IDeviceObserver.aidl
  2. package android.app.devicemanager;
  3. import android.app.devicemanager.DeviceEntity;
  4. oneway interface IDiviceObserver{
  5. void onBindChanged(int state, int deviceId);
  6. void onStateChanged(int state, int deviceId);
  7. }

framework/base/core/java/android/app/devicemanager/DeviceEntity.aidl

  1. package android.app.devicemanager;
  2. parcelable DeviceEntity;

2.2 报错修改

上述写法会报非常多的错,请参考Android 12  API规范:请参考 https://www.cnblogs.com/wanghongzhu/p/14729469.html 。

针对上述代码所犯的错误,也就是大家在Android 12版本中使用make -j32 framework-minus-apex编译framework层的报错修改。

2.2.1 AIDL文件自动生成的Java文件报错

这是因为AIDL自动生成的Java文件不满足Android 12 framework API的规范:framework层不能直接暴露原生AIDL文件。

修改的方式是在aidl文件上添加@hide,如下所示,这样就可以解决所有AIDL自动生成的文件。(这是扒遍国内全网都没在找到,在Google中才找到的根本解决办法)

  1. //framework/base/core/java/android/app/devicemanager/IDeviceManager.aidl
  2. package android.app.devicemanager;
  3. import android.app.devicemanager.DeviceEntity;
  4. import android.app.devicemanager.IDeviceObserver;
  5. /** @hide */
  6. interface IDeviceManager {
  7. int bindDivice(int deviceId);
  8. DeviceEntity getDeviceEntity(int deviceId);
  9. void registerDeviceObserver(in IDeviceObserver observer);
  10. void unregisterDeviceObserver(in IDeviceObserver observer);
  11. }

out/srcjars/android/app/devicemanager/IDiviceObserver.java:60: error: Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause) [RethrowRemoteException]

out/srcjars/android/app/devicemanager/IDiviceObserver.java:70: error: Missing nullability on method `asBinder` return [MissingNullability]
out/srcjars/android/app/devicemanager/IDiviceObserver.java:75: error: Raw AIDL interfaces must not be exposed: Stub extends Binder [RawAidl]

2.2.2 AIDL文件Observer/Callback/Listener命名报错修改

Observer命名报错,Android Lint 工具对callback和listener有严格的校验,不建议使用Observer作为回调,要用callback或者listener。

  • 当只有一个回调方法且永远不会有其他回调方法时使用Listener,且注册监听和解注册监听的方法必须是add/remove开头,否则Android Lint编译不过。
  • 当有多个回调方法时,或者有关联的常量时,应该使用Callback。Callback类可以是一个interface或者abstract class。添加callback和去掉callback应该使用register和unregister开头的方法。
  • callback中的方法应该以on-开头。

请中招的小伙伴自行修改。

2.2.3 注册方法报错

Registration methods should have overload that accepts delivery Executor: `registerDeviceCallback` [ExecutorRegistration]

是不是一脸懵,看不明白啥意思,以前很早的framework层的manager,没啥参考价值,推荐参考新的manager和API规范,因为现有的注册回调的方法必须是两个参数,其中一个必须为Executor,如下所示。

  1. public void registerFooCallback( @NonNull @CallbackExecutor Executor executor,
  2. @NonNull FooCallback callback)
  3. //unregister方法不需要添加Executor
  4. public void unregisterFooCallback(@NonNull FooCallback callback) {}

 2.2.4 避免使用枚举类enum

在Framework层使用enum会报错:Enums are discouraged in Android APIs [Enum],因此一般都用@intDef代替,使用新的注解表示。

2.2.5 Callback如何让APP访问到

前边2.2.1 AIDL文件自动生成的Java文件报错为了解决需要添加@hide,但是添加该注解后,Apps就访问不到该callback,如何实现Binder通信呢?

解决办法:

  • 创建一个public abstract class DeviceCallback,对apps暴露该类,让Apps添加注册的时候创建该类的实例。
  • 然后再framework层manager中实现DeviceManager类与IDeviceCallback.aidl的一一映射关系。

这样做的好处:

  • 即能避免暴露原生的AIDL文件,而且Apps不用实现ICallback.aidl中所有的方法。

//创建暴露给Apps的抽象类 

  1. //framework/base/core/java/android/app/devicemanager/DeviceCallback.java
  2. package android.app.devicemanager;
  3. public abstract class DiviceCallback {
  4. void onBindChanged(int state, int deviceId);
  5. void onStateChanged(int state, int deviceId);
  6. }

//Manager中对应的映射关系 

  1. //framework/base/core/java/android/app/devicemanager/DeviceManager.java
  2. package android.app.devicemanager;
  3. import android.app.devicemanager.IDeiceCallback;
  4. import android.app.devicemanager.DevoceCallback;
  5. import java.util.concurrent.Executor;
  6. public class DeviceManager {
  7. private ArrayMap<DeviceCallback, DeviceCallbackEntry> mCallbackMap = new ArrayMap<>();
  8. //AIDL ICallback真正实现的类
  9. private static final class DeviceCallbackEntry extends IDeviceCallback.Stub {
  10. final DeviceCallback mCallback;
  11. final Executor mExecutor;
  12. DeviceCallbackEntry( DeviceCallback callback, Executor executor) {
  13. mCallback = callback;
  14. mExecutor = executor;
  15. }
  16. //当Binder server端IDeviceCallback的onBindChanged回调时,会调用Apps端注册的
  17. // DeviceCallback类对应的方法,此时就完成了ICallback到Callback抽象类的映射。
  18. public void onBindChanged(int state, int deviceId) {
  19. mExecutor.executor(() -> mCallback.onBindChanged(state, deviceId));
  20. }
  21. ...
  22. }
  23. public void registerDeviceCallback(@Nullable Executor executor,
  24. @NonNull DeviceCallback callback) {
  25. if(callback == null || mCallbackMap.containsKey(calback)) {
  26. return;
  27. }
  28. DeviceCallbackEntry entry = new DeviceCallbackEntry(callback, executor);
  29. mCallbackMap.put(callback, entry);
  30. final IDeviceManager service = getService();
  31. try {
  32. //注意:此处调用的系统服务对应的注册方法中参数是ICallback的实现类,即entry,
  33. //而不是Apps直接注册的抽象类
  34. service.registerDeviceCallback(entry);
  35. } catch (RemoteException e) {
  36. throw e.rethrowFromSystemServer();
  37. }
  38. }
  39. }

3. Context中定义service name

在frameworks/base/core/java/android/content/Context.java中增加一句

public static final String DEVICE_MANAGER_SERVICE = "device_manager";

4. 编写SystemService

在framework/base/services/core/java/com/android/service/下创建系统服务,如果业务比较复杂,可以创建模块文件夹。

framework/base/services/core/java/com/android/service/devicemanage/DeviceManagerService.java

  • extends IDeviceManager.Stub,重写该AILD文件中方法。该AIDL文件是SystemService与系统manager进行IPC的桥梁。
  • 定义静态内部类Lifecycle,extends SystemService,重写onStart()方法,把DeviceManagerService发布到ServiceManger服务中。
  1. package com.android.service.devicemanager;
  2. import android.app.devicemanager.DeviceEntity;
  3. import android.content.Context;
  4. import android.app.devicemanager.IDeviceManager;
  5. import android.app.devicemanager.IDeviceObserver;
  6. import android.os.RemoteException;
  7. public class DeviceManagerService extends IDeviceManager.Stub {
  8. private final Context mContext;
  9. public DeviceManagerService(Context mContext) {
  10. this.mContext = mContext;
  11. }
  12. public static class Lifecycle extends SystemService {
  13. private final DeciceManagerService mService;
  14. public Lifecycle(Context context) {
  15. super(context);
  16. mService = new DeciceManagerService(context);
  17. }
  18. @Override
  19. public void onStart() {
  20. publishBinderService(Context.DEVICE_MANAGER_SERVICE, mService);
  21. }
  22. }
  23. @Override
  24. public int bindDivice(int deviceId) throws RemoteException {
  25. return 0;
  26. }
  27. @Override
  28. public DeviceEntity getDeviceEntity(int deviceId) throws RemoteException {
  29. return null;
  30. }
  31. @Override
  32. public void registerDeviceObserver(IDeviceObserver observer) {
  33. }
  34. @Override
  35. public void unregisterDeviceObserver(IDeviceObserver observer) throws RemoteException {
  36. }
  37. }

5. 在SystemServer类中注册新增的系统服务

在frameworks/base/services/java/com/android/server/SystemServer.java的startOtherServices()中添加以下代码

  1. t.traceBegin("StartLocationManagerService");
  2. mSystemServiceManager.startService(DeviceManagerService.Lifecycle.class);
  3. t.traceEnd();

6. 编写系统Manager类

在framework/base/core/java/android/app/devicemanager下创建DeviceManager类

  • 在DeviceManager类上加注解@SystemService(),参数是第2步中Context中定义service name。注意该参数与DeviceManagerService中的静态内部类的Lifecycle的onStart()方法中publishBinderService(Context.DEVICE_MANAGER_SERVICE, mService)一致。
  • 实现getService()方法,返回IDeviceManager的单例;
  • 利用Singleton工具类通过Binder获取DeviceManagerService的单例;
  • 对外提供接口,内部实现调用service对应的实现接口。
  1. package android.app.devicemanager;
  2. import android.content.Context;
  3. import android.os.IBinder;
  4. import android.os.RemoteException;
  5. @SystemService(Context.DEVICE_MANAGER_SERVICE)
  6. public class DeviceManager {
  7. private mContext mContext;
  8. private DeviceManager(Context context) {
  9. this.mContext = context;
  10. }
  11. public static IDeviceManager getService() {
  12. return IDeviceManagerSingleton.get();
  13. }
  14. public static final Singleton<IDeviceManager> IDeviceManagerSingleton =
  15. () -> {
  16. final IBinder binder = ServiceManager.getService(Context.DEVICE_MANAGER_SERVICE);
  17. return IDeviceManager.Stub.asInterface(binder);
  18. };
  19. public int bindDivice(int deviceId) {
  20. final IDeviceManager service = getService();
  21. try {
  22. return service.bindDivice(deviceId);
  23. } catch (RemoteException e) {
  24. throw e.rethrowFromSystemServer();
  25. }
  26. }
  27. }

7. 注册系统Manager类

在framework/base/core/java/android/app/SystemServiceRegistry.java类的j静态代码块static{}中增加以下代码

  1. registerService(Context.DEVICE_MANAGER_SERVICE, DeviceManager.class,
  2. new CachedServiceFetcher<DeviceManager>() {
  3. @Override
  4. public DeviceManager createService(ContextImpl ctx) {
  5. return new DeviceManager(ctx.getOuterContext());
  6. }});

8. 应用调用

  1. DeviceManager mDeviceManager = (DeviceManager) mContext.getSystemService(Context.DEVICE_MANAGER_SERVICE);
  2. int deviceId = 1;
  3. mDeviceManager.bindDevice(deviceId);

以上是在framework层添加一个完整SystemService和manager的过程。

在Android 12中添加一个系统service,简直到处踩雷,阅读了整个API规范,各种追踪源码,才把framework层的编译通过,如果你喜欢请收藏或者点赞哦!

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号