如何添加Android Native系统服务

154 阅读2分钟

用通俗易懂的方式讲解这篇Android系统服务开发的技术文章:

我们可以把Android系统想象成一个大型快递公司,Binder机制就是它的物流系统。当我们要添加一个新的系统服务(比如一个计算器服务),需要做以下步骤:

  1. ​定义快递单据(AIDL接口)​
    就像快递需要填写运单,我们先用AIDL语言定义服务能做什么:
aidl
Copy
// 声明这个计算器服务可以提供"打招呼"和"加法"两个功能
interface IHello {
    void hello();
    int sum(int x, int y);
}

这个文件会被编译成C++代码,自动生成物流需要的包装箱(Binder通信代码)。

  1. ​建立快递仓库(服务端)​
    我们创建一个继承自BnHello的类,就像建立专门处理计算器快递的仓库:
cpp
Copy
class MyHelloService : public BnHello {
public:
    // 当收到hello请求时,在系统日志贴个标签
    binder::Status hello() {
        ALOGI("有人调用了打招呼功能");
        return binder::Status();
    }
    
    // 处理加法请求,返回计算结果
    binder::Status sum(int x, int y, int* result) {
        *result = x + y; // 实际计算在这里
        return binder::Status();
    }
};

然后把这个服务注册到系统快递总部(ServiceManager):

cpp
Copy
defaultServiceManager()->addService("MyHelloService", new MyHelloService());
  1. ​创建快递网点(客户端)​
    客户端通过Binder系统查找服务:
cpp
Copy
// 先找到快递总部
sp<IServiceManager> sm = defaultServiceManager();
// 查询"计算器服务"的快递单号
sp<IBinder> binder = sm->getService("MyHelloService");
// 转换成可以直接使用的服务接口
sp<IHello> hello = interface_cast<IHello>(binder);
// 现在可以调用服务了
hello->sum(1, 2, &result); // 结果会是3
  1. ​物流安全管控(SELinux配置)​
    Android系统有严格的安全检查,需要:
  • 给服务快递员颁发工作证(定义helloserver_dt类型)
  • 指定服务包裹的存放区域(file_contexts)
  • 登记服务在快递总部的备案信息(service_contexts)
  • 允许快递员使用物流通道(binder权限)
  1. ​为什么客户端不用配权限?​
    客户端就像普通用户寄快递,使用的是系统默认的公共通道。而服务端像物流公司的内部员工,需要特别授权才能处理包裹。但如果是敏感操作,客户端也需要配置权限。

整个过程就像在物流公司里新建一个部门:

  1. 设计服务项目(AIDL)
  2. 建立处理中心(服务端)
  3. 开通对外窗口(客户端)
  4. 办理各种经营许可(SELinux)

通过Binder这个物流系统,不同程序就像发快递一样安全地互相传递数据。这种设计既保证了效率,又确保了系统的安全性。