OpenHarmony轻量系统服务管理|系统服务管理之服务和功能详解
前言
本文是对Samgr部分中子主题Service和Feature的总体概述。服务和功能的耦合度较高,这篇做一个总体概述。
服务和功能概述
在鸿蒙的系统服务管理中,服务(Service)和功能(Feature)是极其重要的基础核心对象。一个服务可以提供零个或多个子功能,它代表一组紧密相关的功能或者操作,通过各种子功能处理服务间的交互操作。下面给出服务和功能的基类结构,当开发自定义的服务和功能时必须从它们继承。 服务基类包括获取服务名(GetName)、服务初始化(Initialize)、消息处理(MessageHandle)、获取服务任务配置(GetTaskConfig)四个基本的生命周期函数。
1 struct Service { 2 //获取服务名 3 const char *(*GetName)(Service *service); 4 //服务初始化 5 BOOL (*Initialize)(Service *service, Identity identity); 6 //处理服务消息 7 BOOL (*MessageHandle)(Service *service, Request *request); 8 //获取服务的task配置 9 TaskConfig (*GetTaskConfig)(Service *service); 10 };
GetName定义如何获取当前服务的名称,Initialize定义服务的初始化方式,MessageHandle定义当前服务收到请求消息后如何处理,GetTaskConfig定义获取当前服务的任务配置。每一个服务都有一个任务(线程)信息配置,标识消息队列的大小、任务的优先级等,当服务初始化时会分配一个同样配置的任务池。
功能基类包括获取功能名(GetName)、功能初始化(OnInitialize)、停止功能(OnStop)、消息处理(OnMessage)四个基本的生命周期函数。
1 struct Feature { 2 //获取功能名 3 const char *(*GetName)(Feature *feature); 4 //功能初始化 5 void (*OnInitialize)(Feature *feature, Service *parent, Identity identity); 6 //停止功能 7 void (*OnStop)(Feature *feature, Identity identity); 8 //处理功能消息,用于处理调用者通过IUnknown发送的请求 9 BOOL (*OnMessage)(Feature *feature, Request *request); 10 };
实例分析
之前分析了IUnknown的作用及使用过程,它是服务和功能间交互的接口,接下来就分析一下服务和功能如何定义、初始化、注册过程。
开发自己的服务和功能。使用宏定义INHERIT_SERVICE和INHERIT_FEATURE分别继承服务和功能的生命周期函数,然后使用INHERIT_IUNKNOWNENTRY继承对外接口。identity用来标识服务、功能和消息队列的关系。
1 typedef struct ExampleService { 2 INHERIT_SERVICE; //继承服务基类 3 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);//继承默认的对外接口 4 Identity identity; //身份标识 5 } ExampleService; 6 typedef struct DemoFeature { 7 INHERIT_FEATURE; //继承功能基类 8 INHERIT_IUNKNOWNENTRY(MyApi);//继承自定义的对外接口 9 Identity identity; //身份标识 10 Service *parent; //当前功能所属的上层服务 11 } DemoFeature;
创建服务对象和功能对象。使用上面自定义的服务和功能创建相应的对象,并为它们的生命周期函数赋值,这些函数可以是我们自己定义的,也可以使用默认的。这里定义的服务继承了IPC服务端代理,所以通过宏定义SERVER_IPROXY_IMPL_BEGIN初始化一部分成员。在功能未绑定到指定服务时,功能的identity初始化为无效值。
1 //自定义服务实例 2 static ExampleService g_example = { 3 .GetName = GetName, 4 .Initialize = Initialize, 5 .MessageHandle = MyMessageHandle, 6 .GetTaskConfig = MyGetTaskConfig, 7 SERVER_IPROXY_IMPL_BEGIN, 8 .Invoke = NULL, 9 .SyncCall = SyncCall, 10 IPROXY_END, 11 }; 12 //自定义功能实例 13 static DemoFeature g_example = { 14 .GetName = FEATURE_GetName, 15 .OnInitialize = FEATURE_OnInitialize, 16 .OnStop = FEATURE_OnStop, 17 .OnMessage = FEATURE_OnMessage, 18 DEFAULT_IUNKNOWN_ENTRY_BEGIN, 19 .MyCall= FunCall, 20 DEFAULT_IUNKNOWN_ENTRY_END, 21 .identity = {-1, -1, NULL}, 22 };
注册服务和功能。我们先注册自定义的服务,然后再注册自定义的功能。服务的初始化入口是SYSEX_SERVICE_INIT(Init),它调用Init函数向Samgr注册服务和默认接口。功能的初始化入口是SYSEX_FEATURE_INIT(Init),向Samgr注册功能及对外接口。
1 //服务初始化函数 2 static void Init(void) 3 { 4 //注册服务 5 SAMGR_GetInstance()->RegisterService((Service *)&g_example); 6 //为指定服务注册默认接口 7 SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example)); 8 } 9 //功能初始化函数 10 static void Init(void){ 11 //向指定服务注册子功能 12 SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example); 13 //为服务下指定功能注册对外接口 14 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); 15 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了