写点什么

Robot OS 添加开机启动服务

作者:轻口味
  • 2022 年 4 月 23 日
  • 本文字数:1757 字

    阅读完需:约 6 分钟

Robot OS添加开机启动服务

1. 背景

在 Robot OS 架构设计中我们规划了语音、视觉、运动、指令处理四大核心服务,这些服务会放在 framework 层,开机后自动启动运行,我们提供 SDK 与这些服务交互,本文我们分析如何在 framework 层中增加开机自启动服务。


本文以 Android 9.0 系统为主。

2. 定义跨进程通信接口

进入到frameworks/base/core/java/android/os 目录,新增 IDemoService.aidl 接口定义文件:


package android.os; interface IDemoService {    void setValue(int val);    int getValue();}
复制代码


AIDL 只支持传输基本 java 类型数据, 要想传递自定义类, 类需要实现 Parcelable 接口, 如果传递基本类型数组, 需要指定 in out 关键字, 比如 void process(in byte[] input, out byte[] output) , 用 in 还是 out, 只需要记住: 数组如果作为参数, 通过调用端传给被调端, 则使用 in, 如果数组只是用来接受数据, 实际数据是由被调用端来填充的, 则使用 out。


frameworks/base目录,打开 Android.mk 文件,修改 LOCAL_SRC_FILES 变量的值,增加 IDemoService.aidl 源文件:


core/java/android/os/IDemoService.aidl /
复制代码


执行mmm frameworks/base编译 aidl 文件,这里在 9.0 版本会报错:


******************************You have tried to change the API from what has been previously approved.

To make these errors go away, you have two choices: 1) You can add "@hide" javadoc comments to the methods, etc. listed in the errors above.

2) You can update current.txt by executing the following command: make update-api

To submit the revised current.txt to the main Android repository, you will need approval....
复制代码


这里我们直接执行sudo make update-api再重新编译既可,编译整个 base 还是有点耗时间。


执行完后会根据 IDemoService.aidl 生成 IDemoService.Stub 接口。

3. 实现 DemoService

frameworks/base/services/java/com/android/server目录,新增 DemoService.java 文件:


package com.android.server;import android.content.Context;import android.os.IDemoService;import android.util.Slog;public class DemoService extends IDemoService.Stub {  private static final String TAG = "DemoService";  private int value;  DemoService() {    Log.i(TAG, "DemoSerice init")  }  public void setValueint val) {    this.value = val;  }    public int getValue() {    return value;  }};
复制代码


DemoService 什么也没干,只是维护了一个 int 型变量,可供 APP 侧获取或者赋值。


修改同目录的 SystemServer.java 文件,在 ServerThread::run 函数中增加加载 DemoService 的代码:


@Override
public void run() {undefined
...... try {undefined Slog.i(TAG, "DiskStats Service"); ServiceManager.addService("diskstats", new DiskStatsService(context)); } catch (Throwable e) {undefined Slog.e(TAG, "Failure starting DiskStats Service", e); }
try { Slog.i(TAG, "Demo Service"); ServiceManager.addService("hello", new DemoService()); } catch (Throwable e) { Slog.e(TAG, "Failure starting Demo Service", e); } ......
复制代码


调用我们的编译打包命令编译出镜像头,烧制到设备,开机后就可以看到我们的Demo ServiceDemoSerice init的日志了。

4. 验证接口

我们自己创建一个 Android 工程,里面实现一个 acitivity,通过导包:import android.os.IDemoService;后,可以通过:


IDemoService demoService = IDemoService.Stub.asInterface(    ServiceManager.getService("demo"));
复制代码


来获取 DemoService,然后通过 IDemoService 多态来调用 get 和 set 方法。

5. 其他实现方式

首先,我们可以不修改 android.os 包,而是把 IDemoService.Stub 的库封装到 SDK 供 APP 使用,或者通过修改 Context,在 Context 中提供获取 DemoService 的接口。


其次,我们可以做成一个单独的 APK,内置到系统,开机启动并提供服务。

6. 总结

本文提供了 framework 层添加系统服务的方式,主要是介绍修改代码的位置,后续我们基于这个思路实现我们架构设计中规划的四个核心服务,并提供 SDK 供 APP 层调用。

发布于: 刚刚阅读数: 2
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017.10.17 加入

Android、音视频、AI相关领域从业者。 欢迎加我微信wodekouwei拉您进InfoQ音视频沟通群 邮箱:qingkouwei@gmail.com

评论

发布
暂无评论
Robot OS添加开机启动服务_android_轻口味_InfoQ写作社区