HarmonyOS APP服务发布与发现:SA注册与获取
【摘要】 服务发布与发现:SA注册与获取让服务"自动发现",告别硬编码地址 一、背景与动机:为什么需要服务发现? 1.1 传统方式的问题假设你开发了一个支付服务,其他应用需要调用它。传统做法是:// ❌ 硬编码服务地址const paymentService = connectToService('192.168.1.100:8080')// 问题:// 1. 服务地址变化时,所有客户端都要修改//...
服务发布与发现:SA注册与获取
让服务"自动发现",告别硬编码地址
一、背景与动机:为什么需要服务发现?
1.1 传统方式的问题
假设你开发了一个支付服务,其他应用需要调用它。传统做法是:
// ❌ 硬编码服务地址
const paymentService = connectToService('192.168.1.100:8080')
// 问题:
// 1. 服务地址变化时,所有客户端都要修改
// 2. 服务迁移到其他设备,客户端无法知道
// 3. 多实例部署时,无法负载均衡
// 4. 服务不可用时,无法自动切换
**服务发现(Service Discovery)**解决了这些问题:
// ✅ 服务发现
const paymentService = await ServiceManager.getService('com.example.payment')
// 优势:
// 1. 服务地址动态获取
// 2. 自动感知服务状态
// 3. 支持多实例负载均衡
// 4. 服务不可用时自动切换
1.2 鸿蒙的SA机制
鸿蒙使用**SA(System Ability)**机制管理服务:
| 概念 | 说明 |
|---|---|
| System Ability | 系统能力,即服务 |
| SAMgr | 系统能力管理器,负责注册和发现 |
| SA ID | 服务的唯一标识 |
| SA Proxy | 服务代理,用于跨进程调用 |

1.3 SA vs 传统RPC
| 对比项 | 传统RPC | 鸿蒙SA |
|---|---|---|
| 服务地址 | 硬编码IP:Port | 动态发现 |
| 服务状态 | 手动检测 | 自动感知 |
| 负载均衡 | 客户端实现 | 系统实现 |
| 服务迁移 | 需要通知 | 自动适应 |
| 权限控制 | 应用层实现 | 系统级控制 |
二、核心原理:SA工作机制
2.1 SA生命周期
sequenceDiagram
participant SA as System Ability
participant SAMgr as SAMgr
participant Client as 客户端
Note over SA: 服务启动
SA->>SAMgr: 注册(SA ID, IRemoteObject)
SAMgr->>SAMgr: 保存到注册表
Note over Client: 客户端请求
Client->>SAMgr: 查询(SA ID)
SAMgr->>SAMgr: 查找注册表
SAMgr-->>Client: 返回SA Proxy
Client->>SA: 调用方法(通过Proxy)
SA-->>Client: 返回结果
Note over SA: 服务停止
SA->>SAMgr: 注销(SA ID)
SAMgr->>SAMgr: 从注册表移除
classDef primary fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef warning fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef success fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
class SA success
class SAMgr warning
class Client primary
2.2 SA ID分配
每个SA都有唯一的ID,分为系统SA和应用SA:
// SA ID范围
// 0x00000001 - 0x0000FFFF: 系统SA
// 0x00010000 - 0x0001FFFF: 应用SA
// 系统SA示例
const SAMGR_SA_ID = 0x00000001 // SAMgr自身
const BUNDLE_MGR_SA_ID = 0x00000002 // 包管理服务
const ACCOUNT_MGR_SA_ID = 0x00000003 // 账号管理服务
// 应用SA示例(需要申请)
const MY_PAYMENT_SA_ID = 0x00010001 // 自定义支付服务
const MY_PUSH_SA_ID = 0x00010002 // 自定义推送服务
2.3 SA Proxy获取流程
// SAMgr内部实现(伪代码)
class SAMgr {
private registry: Map<number, IRemoteObject> = new Map()
// 注册SA
register(saId: number, remote: IRemoteObject): boolean {
if (this.registry.has(saId)) {
// SA已存在,检查是否可覆盖
return false
}
this.registry.set(saId, remote)
return true
}
// 获取SA
get(saId: number): IRemoteObject {
const remote = this.registry.get(saId)
if (!remote) {
// SA不存在,尝试按需启动
this.startOnDemand(saId)
return this.registry.get(saId)
}
return remote
}
// 注销SA
unregister(saId: number): boolean {
return this.registry.delete(saId)
}
// 按需启动
async startOnDemand(saId: number): Promise<void> {
// 根据SA ID查找对应的进程
// 启动进程并等待SA注册
}
}
三、代码实战:实现支付服务SA
3.1 定义SA接口
// IPaymentService.ets
import { IRemoteObject } from '@kit.IPCKit'
/**
* 支付服务接口
*/
export interface IPaymentService {
/**
* 创建支付订单
* @param order 订单信息
* @returns 订单ID
*/
createOrder(order: PaymentOrder): Promise<string>
/**
* 查询订单状态
* @param orderId 订单ID
* @returns 订单状态
*/
queryOrder(orderId: string): Promise<OrderStatus>
/**
* 取消订单
* @param orderId 订单ID
* @returns 是否成功
*/
cancelOrder(orderId: string): Promise<boolean>
/**
* 获取RemoteObject引用
*/
asObject(): IRemoteObject
}
/**
* 支付订单
*/
export interface PaymentOrder {
amount: number // 金额(分)
currency: string // 币种
subject: string // 商品名称
body?: string // 商品描述
userId: string // 用户ID
notifyUrl?: string // 回调URL
}
/**
* 订单状态
*/
export interface OrderStatus {
orderId: string
status: 'pending' | 'paid' | 'failed' | 'cancelled'
amount: number
paidAt?: number
transactionId?: string
}
// 请求码定义
export const enum PaymentCode {
CREATE_ORDER = 1,
QUERY_ORDER = 2,
CANCEL_ORDER = 3
}
// SA ID定义
export const PAYMENT_SA_ID = 0x00010001
// 接口描述符
export const PAYMENT_DESCRIPTOR = 'com.example.IPaymentService'
3.2 实现SA服务端
// PaymentService.ets
import { SystemAbility, MessageParcel, IRemoteObject } from '@kit.IPCKit'
import { IPaymentService, PaymentOrder, OrderStatus, PaymentCode, PAYMENT_SA_ID, PAYMENT_DESCRIPTOR } from './IPaymentService'
import hilog from '@ohos.hilog'
const TAG = 'PaymentService'
const DOMAIN = 0xFF00
/**
* 支付服务SA实现
*/
export default class PaymentService extends SystemAbility implements IPaymentService {
// 订单存储(实际应使用数据库)
private orders: Map<string, OrderInfo> = new Map()
/**
* SA启动时调用
*/
onStart(): void {
hilog.info(DOMAIN, TAG, 'PaymentService onStart')
// 注册到SAMgr
this.registerToSAMgr()
// 初始化资源
this.initialize()
}
/**
* SA停止时调用
*/
onStop(): void {
hilog.info(DOMAIN, TAG, 'PaymentService onStop')
// 注销SA
this.unregisterFromSAMgr()
// 清理资源
this.cleanup()
}
/**
* 注册到SAMgr
*/
private registerToSAMgr(): void {
// SystemAbility基类会自动注册
// 这里可以添加额外的注册逻辑
hilog.info(DOMAIN, TAG, `Registered with SA ID: ${PAYMENT_SA_ID}`)
}
/**
* 注销SA
*/
private unregisterFromSAMgr(): void {
hilog.info(DOMAIN, TAG, 'Unregistered from SAMgr')
}
/**
* 初始化
*/
private initialize(): void {
// 加载订单数据
// 连接支付渠道
hilog.info(DOMAIN, TAG, 'PaymentService initialized')
}
/**
* 清理资源
*/
private cleanup(): void {
this.orders.clear()
hilog.info(DOMAIN, TAG, 'PaymentService cleaned up')
}
/**
* 处理远程请求
*/
onRemoteRequest(code: number, data: MessageParcel, reply: MessageParcel): boolean {
hilog.info(DOMAIN, TAG, `onRemoteRequest: code=${code}`)
switch (code) {
case PaymentCode.CREATE_ORDER:
return this.handleCreateOrder(data, reply)
case PaymentCode.QUERY_ORDER:
return this.handleQueryOrder(data, reply)
case PaymentCode.CANCEL_ORDER:
return this.handleCancelOrder(data, reply)
default:
hilog.warn(DOMAIN, TAG, `Unknown code: ${code}`)
return false
}
}
/**
* 处理创建订单请求
*/
private handleCreateOrder(data: MessageParcel, reply: MessageParcel): boolean {
try {
// 读取订单信息
const orderJson = data.readString()
const order: PaymentOrder = JSON.parse(orderJson)
// 创建订单
const orderId = this.createOrderInternal(order)
// 写入响应
reply.writeString(orderId)
hilog.info(DOMAIN, TAG, `Order created: ${orderId}`)
return true
} catch (err) {
hilog.error(DOMAIN, TAG, `Create order failed: ${err.message}`)
reply.writeString('')
return false
}
}
/**
* 处理查询订单请求
*/
private handleQueryOrder(data: MessageParcel, reply: MessageParcel): boolean {
try {
const orderId = data.readString()
const status = this.queryOrderInternal(orderId)
reply.writeString(JSON.stringify(status))
return true
} catch (err) {
hilog.error(DOMAIN, TAG, `Query order failed: ${err.message}`)
return false
}
}
/**
* 处理取消订单请求
*/
private handleCancelOrder(data: MessageParcel, reply: MessageParcel): boolean {
try {
const orderId = data.readString()
const success = this.cancelOrderInternal(orderId)
reply.writeBoolean(success)
return true
} catch (err) {
hilog.error(DOMAIN, TAG, `Cancel order failed: ${err.message}`)
return false
}
}
/**
* 创建订单(内部实现)
*/
private createOrderInternal(order: PaymentOrder): string {
// 生成订单ID
const orderId = `ORD${Date.now()}${Math.random().toString(36).substr(2, 9)}`
// 保存订单
const orderInfo: OrderInfo = {
orderId: orderId,
order: order,
status: 'pending',
createdAt: Date.now()
}
this.orders.set(orderId, orderInfo)
// 异步处理支付
this.processPayment(orderId, order)
return orderId
}
/**
* 查询订单(内部实现)
*/
private queryOrderInternal(orderId: string): OrderStatus {
const info = this.orders.get(orderId)
if (!info) {
return {
orderId: orderId,
status: 'failed',
amount: 0
}
}
return {
orderId: info.orderId,
status: info.status,
amount: info.order.amount,
paidAt: info.paidAt,
transactionId: info.transactionId
}
}
/**
* 取消订单(内部实现)
*/
private cancelOrderInternal(orderId: string): boolean {
const info = this.orders.get(orderId)
if (!info || info.status !== 'pending') {
return false
}
info.status = 'cancelled'
return true
}
/**
* 处理支付(异步)
*/
private async processPayment(orderId: string, order: PaymentOrder): Promise<void> {
// 模拟支付处理
await new Promise(resolve => setTimeout(resolve, 2000))
const info = this.orders.get(orderId)
if (!info || info.status !== 'pending') {
return
}
// 模拟支付成功
info.status = 'paid'
info.paidAt = Date.now()
info.transactionId = `TXN${Date.now()}`
hilog.info(DOMAIN, TAG, `Payment completed: ${orderId}`)
// 通知回调
if (order.notifyUrl) {
this.notifyPayment(order.notifyUrl, info)
}
}
/**
* 通知支付结果
*/
private async notifyPayment(url: string, info: OrderInfo): Promise<void> {
// 发送HTTP通知
hilog.info(DOMAIN, TAG, `Notify: ${url}`)
}
/**
* 实现IPaymentService接口
*/
async createOrder(order: PaymentOrder): Promise<string> {
return this.createOrderInternal(order)
}
async queryOrder(orderId: string): Promise<OrderStatus> {
return this.queryOrderInternal(orderId)
}
async cancelOrder(orderId: string): Promise<boolean> {
return this.cancelOrderInternal(orderId)
}
asObject(): IRemoteObject {
return this
}
}
/**
* 订单信息(内部)
*/
interface OrderInfo {
orderId: string
order: PaymentOrder
status: 'pending' | 'paid' | 'failed' | 'cancelled'
createdAt: number
paidAt?: number
transactionId?: string
}
3.3 配置SA
// module.json5
{
"module": {
"name": "entry",
"type": "entry",
"abilities": [
{
"name": "PaymentService",
"srcEntry": "./ets/PaymentService.ets",
"type": "service",
"visible": true,
"systemAbility": {
"saId": 4294967297, // 0x00010001的十进制
"permission": "ohos.permission.PAYMENT_SERVICE",
"distributed": true, // 支持分布式
"dumpLevel": 1
}
}
]
}
}
3.4 客户端获取SA
// PaymentClient.ets
import { samgr, IRemoteObject } from '@kit.IPCKit'
import { IPaymentService, PaymentOrder, OrderStatus, PAYMENT_SA_ID, PAYMENT_DESCRIPTOR } from './IPaymentService'
import { MessageParcel } from '@kit.IPCKit'
import hilog from '@ohos.hilog'
const TAG = 'PaymentClient'
const DOMAIN = 0xFF00
/**
* 支付服务代理
*/
export class PaymentProxy implements IPaymentService {
private remote: IRemoteObject
constructor(remote: IRemoteObject) {
this.remote = remote
}
/**
* 创建订单
*/
async createOrder(order: PaymentOrder): Promise<string> {
const data = MessageParcel.create()
const reply = MessageParcel.create()
try {
data.writeString(JSON.stringify(order))
const result = this.remote.sendRequest(1, data, reply)
if (!result) {
throw new Error('sendRequest failed')
}
return reply.readString()
} finally {
data.reclaim()
reply.reclaim()
}
}
/**
* 查询订单
*/
async queryOrder(orderId: string): Promise<OrderStatus> {
const data = MessageParcel.create()
const reply = MessageParcel.create()
try {
data.writeString(orderId)
this.remote.sendRequest(2, data, reply)
const json = reply.readString()
return JSON.parse(json) as OrderStatus
} finally {
data.reclaim()
reply.reclaim()
}
}
/**
* 取消订单
*/
async cancelOrder(orderId: string): Promise<boolean> {
const data = MessageParcel.create()
const reply = MessageParcel.create()
try {
data.writeString(orderId)
this.remote.sendRequest(3, data, reply)
return reply.readBoolean()
} finally {
data.reclaim()
reply.reclaim()
}
}
asObject(): IRemoteObject {
return this.remote
}
}
/**
* 支付服务客户端
*/
export class PaymentClient {
private paymentService: IPaymentService = null
/**
* 连接支付服务
*/
async connect(): Promise<void> {
try {
// 从SAMgr获取SA
const remote = await samgr.getSystemAbility(PAYMENT_SA_ID)
if (!remote) {
throw new Error('Payment service not available')
}
// 创建代理
this.paymentService = new PaymentProxy(remote)
hilog.info(DOMAIN, TAG, 'Connected to payment service')
} catch (err) {
hilog.error(DOMAIN, TAG, `Connect failed: ${err.message}`)
throw err
}
}
/**
* 创建支付订单
*/
async createOrder(order: PaymentOrder): Promise<string> {
if (!this.paymentService) {
await this.connect()
}
return this.paymentService.createOrder(order)
}
/**
* 查询订单状态
*/
async queryOrder(orderId: string): Promise<OrderStatus> {
if (!this.paymentService) {
await this.connect()
}
return this.paymentService.queryOrder(orderId)
}
/**
* 取消订单
*/
async cancelOrder(orderId: string): Promise<boolean> {
if (!this.paymentService) {
await this.connect()
}
return this.paymentService.cancelOrder(orderId)
}
/**
* 断开连接
*/
disconnect(): void {
this.paymentService = null
hilog.info(DOMAIN, TAG, 'Disconnected from payment service')
}
}
3.5 使用示例
// PaymentPage.ets
import { PaymentClient, PaymentOrder } from './PaymentClient'
import hilog from '@ohos.hilog'
const TAG = 'PaymentPage'
const DOMAIN = 0xFF00
@Entry
@Component
struct PaymentPage {
@State orderId: string = ''
@State orderStatus: string = ''
@State isLoading: boolean = false
private paymentClient: PaymentClient = new PaymentClient()
async aboutToAppear() {
try {
await this.paymentClient.connect()
} catch (err) {
hilog.error(DOMAIN, TAG, `Connect failed: ${err.message}`)
}
}
aboutToDisappear() {
this.paymentClient.disconnect()
}
/**
* 创建订单
*/
async createOrder(): Promise<void> {
this.isLoading = true
try {
const order: PaymentOrder = {
amount: 10000, // 100元
currency: 'CNY',
subject: '鸿蒙开发课程',
body: '从入门到精通',
userId: 'user001',
notifyUrl: 'https://example.com/notify'
}
this.orderId = await this.paymentClient.createOrder(order)
this.orderStatus = '订单创建成功'
hilog.info(DOMAIN, TAG, `Order created: ${this.orderId}`)
// 轮询订单状态
this.pollOrderStatus()
} catch (err) {
this.orderStatus = `创建失败: ${err.message}`
} finally {
this.isLoading = false
}
}
/**
* 轮询订单状态
*/
private async pollOrderStatus(): Promise<void> {
for (let i = 0; i < 10; i++) {
await new Promise(resolve => setTimeout(resolve, 2000))
try {
const status = await this.paymentClient.queryOrder(this.orderId)
this.orderStatus = `订单状态: ${status.status}`
if (status.status === 'paid') {
// 支付成功
this.orderStatus = '支付成功!'
break
} else if (status.status === 'failed') {
this.orderStatus = '支付失败'
break
}
} catch (err) {
hilog.error(DOMAIN, TAG, `Query failed: ${err.message}`)
}
}
}
/**
* 取消订单
*/
async cancelOrder(): Promise<void> {
if (!this.orderId) {
return
}
try {
const success = await this.paymentClient.cancelOrder(this.orderId)
if (success) {
this.orderStatus = '订单已取消'
} else {
this.orderStatus = '取消失败'
}
} catch (err) {
this.orderStatus = `取消失败: ${err.message}`
}
}
build() {
Column() {
Text('支付服务示例')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
if (this.isLoading) {
LoadingProgress()
.width(50)
.height(50)
} else {
// 订单信息
if (this.orderId) {
Text(`订单ID: ${this.orderId}`)
.fontSize(14)
.margin({ bottom: 10 })
}
Text(this.orderStatus)
.fontSize(16)
.margin({ bottom: 20 })
// 操作按钮
Row() {
Button('创建订单')
.onClick(() => this.createOrder())
.margin({ right: 10 })
Button('取消订单')
.onClick(() => this.cancelOrder())
.enabled(!!this.orderId)
}
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
四、踩坑与注意事项
4.1 坑一:SA ID冲突
问题:多个应用使用相同的SA ID会导致冲突。
// ❌ 使用系统SA ID范围
const MY_SA_ID = 0x00000010 // 系统SA ID,可能冲突
// ✅ 使用应用SA ID范围
const MY_SA_ID = 0x00010001 // 应用SA ID起始
// ✅ 更好:向系统申请专用SA ID
// 在profile中声明,系统会分配唯一ID
4.2 坑二:SA未启动
问题:SA可能未启动,获取时返回null。
// ❌ 直接使用,不检查
const remote = await samgr.getSystemAbility(SA_ID)
remote.sendRequest(...) // remote可能是null
// ✅ 检查并处理
async function getSA(saId: number): Promise<IRemoteObject> {
let remote = await samgr.getSystemAbility(saId)
if (!remote) {
// SA未启动,尝试启动
await samgr.startSystemAbility(saId)
// 等待SA启动
await new Promise(resolve => setTimeout(resolve, 1000))
// 再次获取
remote = await samgr.getSystemAbility(saId)
}
if (!remote) {
throw new Error('SA not available')
}
return remote
}
4.3 坑三:权限不足
问题:访问系统SA需要相应权限。
// ❌ 无权限访问系统SA
const remote = await samgr.getSystemAbility(ACCOUNT_MGR_SA_ID)
// 可能抛出权限异常
// ✅ 检查权限
async function getAccountSA(): Promise<IRemoteObject | null> {
try {
return await samgr.getSystemAbility(ACCOUNT_MGR_SA_ID)
} catch (err) {
if (err.code === 201 || err.code === 202) {
// 权限不足
hilog.error(DOMAIN, TAG, 'Permission denied')
return null
}
throw err
}
}
4.4 坑四:SA状态监听
问题:SA可能随时停止,需要监听状态变化。
// ✅ 注册SA状态监听
import { samgr, SystemAbilityStatusChange } from '@kit.IPCKit'
class SAStatusListener {
// 注册状态变化监听
registerListener(saId: number): void {
const listener: SystemAbilityStatusChange = {
onAddSystemAbility: (saId: number, deviceId: string) => {
hilog.info(DOMAIN, TAG, `SA ${saId} added on ${deviceId}`)
// SA可用,可以获取使用
},
onRemoveSystemAbility: (saId: number, deviceId: string) => {
hilog.info(DOMAIN, TAG, `SA ${saId} removed on ${deviceId}`)
// SA不可用,需要处理
}
}
samgr.subscribeSystemAbility(saId, listener)
}
// 注销监听
unregisterListener(saId: number): void {
samgr.unsubscribeSystemAbility(saId)
}
}
五、HarmonyOS 6适配指南
5.1 API变更
| 变更项 | HarmonyOS 5 | HarmonyOS 6 |
|---|---|---|
| 导入方式 | @ohos.samgr |
@kit.IPCKit |
| 获取SA | getSystemAbility |
同上 |
| 启动SA | startSystemAbility |
同上 |
| 分布式支持 | 有限 | 完整支持 |
5.2 新增功能
// HarmonyOS 6新增:分布式SA
import { samgr } from '@kit.IPCKit'
// 获取远程设备上的SA
async function getRemoteSA(deviceId: string, saId: number): Promise<IRemoteObject> {
const remote = await samgr.getSystemAbility(saId, deviceId)
return remote
}
// HarmonyOS 6新增:SA能力查询
async function querySACapability(saId: number): Promise<SACapability> {
const capability = await samgr.querySystemAbilityInfo(saId)
return {
isRunning: capability.isRunning,
isDistributed: capability.isDistributed,
permission: capability.permission,
deviceId: capability.deviceId
}
}
// HarmonyOS 6新增:批量获取SA
async function batchGetSA(saIds: number[]): Promise<Map<number, IRemoteObject>> {
const results = new Map()
for (const saId of saIds) {
const remote = await samgr.getSystemAbility(saId)
if (remote) {
results.set(saId, remote)
}
}
return results
}
5.3 分布式SA示例
// DistributedPayment.ets
import { samgr, deviceManager } from '@kit.IPCKit'
import hilog from '@ohos.hilog'
const TAG = 'DistributedPayment'
const DOMAIN = 0xFF00
/**
* 分布式支付服务客户端
* 可以调用本地或远程设备上的支付服务
*/
export class DistributedPaymentClient {
/**
* 获取最佳支付服务
* 优先本地,其次远程设备
*/
async getBestPaymentService(): Promise<IPaymentService> {
// 尝试本地
let remote = await samgr.getSystemAbility(PAYMENT_SA_ID)
if (remote) {
hilog.info(DOMAIN, TAG, 'Using local payment service')
return new PaymentProxy(remote)
}
// 尝试远程设备
const devices = await this.getAvailableDevices()
for (const device of devices) {
remote = await samgr.getSystemAbility(PAYMENT_SA_ID, device.deviceId)
if (remote) {
hilog.info(DOMAIN, TAG, `Using remote payment service on ${device.deviceName}`)
return new PaymentProxy(remote)
}
}
throw new Error('No payment service available')
}
/**
* 获取可用设备列表
*/
private async getAvailableDevices(): Promise<DeviceInfo[]> {
// 使用deviceManager获取设备列表
const dmInstance = deviceManager.createDeviceManager('com.example.app')
const devices = dmInstance.getTrustedDeviceListSync()
return devices.filter(d => d.deviceState === 'ONLINE')
}
}
六、总结
6.1 核心要点回顾

6.2 最佳实践清单
- [ ] 使用正确的SA ID范围
- [ ] 检查SA是否可用
- [ ] 处理权限不足的情况
- [ ] 注册SA状态监听
- [ ] 实现SA Proxy封装调用
- [ ] 支持分布式场景
- [ ] 正确配置SA权限
6.3 SA vs 其他方案
| 场景 | 推荐方案 |
|---|---|
| 系统服务 | 系统SA |
| 应用服务 | 应用SA |
| 跨应用通信 | SA或DataShare |
| 跨设备通信 | 分布式SA |
| 简单数据共享 | DataShare |
| 复杂业务逻辑 | SA |
下一篇预告:《跨进程回调:RemoteObject回调机制》——深入跨进程回调的实现原理。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)