【华为根技术】
把鸿蒙玩明白:一次真正意义上的“自定义系统服务”开发实践
作者:Echo_Wish
引子:当我们第一次想“加点自己的系统能力”时
兄弟姐妹们,做鸿蒙开发的,大多都经历过这么个瞬间:
“要是我能自己写个系统服务就好了!”
比如:
- 想让应用能实时获取室温 + 电量 + 某个硬件传感器的组合信息
- 想做一个系统级能力,比如应用启动审计、设备行为记录、统一策略管理
- 想扩展鸿蒙原生能力,但又不想每次都在应用层“曲线救国”
这时你会发现:
应用侧 API 不够用,框架层能力不可改,那就只能自己写系统服务(System Ability)了。
很多人一听“系统服务”就觉得玄乎,觉得是系统工程师才能写,
实际上它真的没有想象中那么神秘。
今天,我就带你来一次“看得懂、能上手、有温度”的 鸿蒙自定义系统服务开发实践。
结构我已经想好了,跟平时咱聊天一样:
引子(你刚读完) → 原理(不烧脑) → 实战代码 → 场景应用 → Echo_Wish思考
开整。
一、原理讲解:系统服务到底是什么?(不烧脑版)
在鸿蒙系统里,系统服务(System Ability)= 系统级常驻后台能力。
有三件事你必须要知道:
① 系统服务是“SystemAbilityManager”托管的
鸿蒙系统有个大管家:
SystemAbilityManager(SAMgr)
所有系统服务都要:
- 注册到它
- 由它启动
- 通过它暴露接口
- 通过它被跨进程调用
你写的服务本质上就是:
“一个由 SAMgr 托管的、带 IPC 能力的后台常驻进程”。
② 系统服务必须定义接口(IPC Stub/Proxy)
鸿蒙使用 IDL → IPC Stub/Proxy → Service端实现 的通信模式。
简单讲:
- IXXXXInterface.idl:定义你服务能提供什么能力
- Stub:服务端接收请求
- Proxy:客户端发起请求
- ServiceImpl:真正处理逻辑
③ 只有 SystemAbility 可以被全局调用
应用只能访问系统服务,不允许直接访问系统内部模块。
所以你想扩展鸿蒙系统级能力,系统服务就是唯一入口。
好,原理就这么多,够用了。
下面我们上硬菜:写一个真的能跑的自定义系统服务。
二、实战代码:写一个“DeviceInfo增强服务”(可跑可调)
假设我们要写一个系统服务:
获取设备 CPU + 内存 + 电池的综合信息,提供给应用调用。
服务名:CustomDeviceInfoService
系统能力 ID:5600xxx
① 定义 IDL 接口(IXXXXX.idl)
interface IDeviceInfoService {
GetDeviceSummary() returns (String summary);
}
这里定义了一个最关键的方法:GetDeviceSummary。
所有跨进程调用都依赖 IDL。
② 服务端实现 Stub
class DeviceInfoStub : public IRemoteStub<IDeviceInfoService> {
public:
int OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) override
{
switch (code) {
case GET_DEVICE_SUMMARY: {
std::string result = GetDeviceSummary();
reply.WriteString(result);
return NO_ERROR;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
std::string GetDeviceSummary()
{
return "cpu:20%, mem:45%, battery:88%";
}
};
Stub 是服务端接受 IPC 调用的入口。
③ 实现 SystemAbility 服务
class DeviceInfoService : public SystemAbility, public DeviceInfoStub {
public:
DECLARE_SYSTEM_ABILITY(DeviceInfoService);
DeviceInfoService(int32_t systemAbilityId, bool runOnCreate)
: SystemAbility(systemAbilityId, runOnCreate) {}
void OnStart() override
{
bool res = Publish(this);
if (!res) {
HILOG_ERROR("Publish DeviceInfoService failed");
}
}
void OnStop() override {}
};
REGISTER_SYSTEM_ABILITY(DeviceInfoService);
重点是 Publish(this)
这一步把你的服务发布给 SystemAbilityManager。
从此,你的服务就具备“系统可见性”。
④ 客户端调用(应用或其他服务)
sptr<IDeviceInfoService> GetDeviceInfoProxy()
{
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
auto obj = sam->GetSystemAbility(5600xxx);
return iface_cast<IDeviceInfoService>(obj);
}
void TestCall() {
auto proxy = GetDeviceInfoProxy();
std::string info = proxy->GetDeviceSummary();
std::cout << info << std::endl;
}
只要你知道 SystemAbilityId,任何地方都能调用。
三、场景应用:系统服务“到底能派什么用场”?
说句良心话:
能用到系统服务的团队,一般都在做大东西。
比如:
✔ ① 全局设备策略控制(企业 / IoT)
- 禁用某些应用
- 全局流量策略
- 设备统一管控
- MDM 设备策略下发
系统服务最适合干这个。
✔ ② 自定义硬件能力(车载 / IoT / 可穿戴)
鸿蒙偏 软硬件协同架构,你想接:
- 私有传感器
- 自定义芯片接口
- 底层硬件驱动扩展
系统服务是你唯一入口。
✔ ③ 应用级能力升级(跨应用共享能力)
比如你想做一个统一的:
- OCR 服务
- ML 推理服务
- 图像处理服务
- 数据分析服务
不想每个 App 都集成一份?
统一做一个系统服务就完事了。
✔ ④ 系统行为监控 & 安全风控
- 应用启动拦截
- 系统行为审计
- 文件访问监控
- 高危操作检测
这种必须系统层做。
四、Echo_Wish式思考:写系统服务,到底在锻炼什么?
这部分我想说点心里话。
做自定义系统服务,看似是“技术能力的提升”,
但其实它真正提升的是:
① 你对鸿蒙体系的理解深度
从应用层 → 框架层 → 系统服务层
每上升一级,你的视角都会改变。
你会从“怎么写业务”
变成“怎么设计能力”。
② 你对系统架构的“掌控能力”
系统服务不是“为了写而写”。
它要求你:
- 理解系统启动流程
- 会设计 IPC 接口
- 会划分系统能力边界
- 会考虑多进程协同
- 会思考安全与权限
这才是真正的系统思维。
③ 你开始理解“为什么鸿蒙是一个系统,而不是一个手机 OS”
当你能写自己的系统服务时,
你就理解了鸿蒙的核心价值:
系统能力可扩展,生态能力可重组。
你不再只是 App 开发者,
你是在参与系统的建设者。
最后:如果你想,我还能带你做一个可跑的“真实项目”
比如:
- 自定义传感器系统服务
- 系统级 OCR 服务
- 自定义策略中心
- 分布式能力管理服务
- 点赞
- 收藏
- 关注作者
评论(0)