You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

在Android 11自定义系统中创建AIDL接口与SystemService通信报错

解决方案

针对Android 11自定义系统中公开AIDL接口的编译错误问题,需要严格遵循系统SDK接口的发布规范,以下是具体步骤:

1. 调整AIDL文件结构与构建配置

  • 不要将AIDL直接放在android.os包下,建议新建专属包(如android.test),将ITest.aidl放在frameworks/base/core/java/android/test/路径下,接口名统一加I前缀符合系统命名规范:
    package android.test;
    
    interface ITest {
        void test();
    }
    
  • frameworks/base/Android.bp中添加AIDL接口的构建配置,明确标记为公开SDK接口:
    aidl_interface {
        name: "android.test.ITest",
        srcs: ["core/java/android/test/ITest.aidl"],
        stability: "vintf",
        sdk_version: "current",
    }
    
    该配置会让构建系统生成符合公开SDK规范的Java代码,解决"RawAidl接口不能暴露"的错误。

2. 修复注解与异常处理问题

  • 空注解:为AIDL方法的参数、返回值添加@Nullable@NonNull注解,比如:
    package android.test;
    
    import android.annotation.Nullable;
    
    interface ITest {
        void test(@Nullable String input);
    }
    
  • RemoteException处理:系统公开接口不能直接抛出RemoteException,需通过Manager类封装调用,将其转为系统RuntimeException。

3. 实现Manager类封装服务调用

创建TestManager作为应用访问服务的入口,封装AIDL调用并处理异常,放在frameworks/base/core/java/android/test/TestManager.java

package android.test;

import android.os.RemoteException;

public class TestManager {
    private final ITest mService;

    public TestManager(ITest service) {
        mService = service;
    }

    public void test() {
        try {
            mService.test();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}

4. 注册服务并暴露访问入口

  • SystemService启动TestService后,将其注册到ServiceManager:
    ServiceManager.addService(Context.TEST_SERVICE, new TestService());
    
  • Context类中添加服务常量:
    public static final String TEST_SERVICE = "test";
    
  • ContextImplgetSystemService方法中添加分支,返回TestManager实例:
    case TEST_SERVICE:
        return new TestManager(ITest.Stub.asInterface(ServiceManager.getService(TEST_SERVICE)));
    

5. 配置公开SDK接口

  • 确保TestManagerITest被加入公开SDK,编译时系统会自动更新frameworks/base/api/current.txt,若需手动补充,添加对应类和方法的声明。
  • 若服务需要权限控制,在TestManager的方法上添加@RequiresPermission注解,同时在系统AndroidManifest.xml中声明权限。

完成以上步骤后,重新编译系统镜像,即可生成符合规范的公开接口,外部应用可通过Context.getSystemService(TestManager.class)getSystemService(Context.TEST_SERVICE)获取实例并调用方法。

内容的提问来源于stack exchange,提问作者tyczj

火山引擎 最新活动