鸿蒙FA/PA架构设计核心信息
一、FA与PA的定义与区别
Feature Ability (FA)
- 定位:用户可直接感知和交互的应用界面部分,是应用的"门面"
- 形态:主要表现为独立的UI页面(Page Ability)
- 特点:
- 必须包含用户界面(使用ArkTS等声明式UI)
- 拥有独立入口,通常在设备桌面上有对应图标
- 具备完整生命周期(onStart, onActive, onInactive, onBackground, onForeground, onStop)
- 支持跨设备启动,实现分布式流转
- 使用场景:应用首页、商品详情页、设置页面等用户交互界面
Particle Ability (PA)
- 定位:应用的后台服务或数据处理能力,是应用的"引擎"
- 形态:主要实现形式为Service Ability和Data Ability
- Service Ability:执行后台运行任务(如下载文件、播放音乐、长时间计算)
- Data Ability:提供统一的数据访问接口(操作本地数据库、文件或跨应用共享数据)
- 特点:
- 通常无UI界面,专注于后台逻辑执行或数据操作
- 不能独立运行,需被FA或其他PA通过Intent或connectAbility方法启动或连接
- 同样拥有生命周期,但触发和管理方式与FA不同
- 支持跨设备调用,是鸿蒙分布式能力的核心体现
- 使用场景:后台音乐播放服务、文件下载服务、位置信息服务、数据库操作封装等
二、FA与PA的关系与协作
核心协作模式
- 解耦与复用:FA和PA的设计实现了前端交互与后端逻辑的分离,使PA可被多个不同FA复用
- 协同工作流程:
- FA负责展示信息和接收用户指令
- 当需要执行耗时操作、访问数据或使用设备能力时,FA启动或连接相应PA
- PA完成任务后将结果返回给FA进行展示或触发后续操作
- 分布式基础:FA和PA均支持跨设备调用,是鸿蒙"一次开发,多端部署"理念的核心实现
AbilitySlice概念
- FA(Page Ability)内部可包含一个或多个AbilitySlice
- AbilitySlice是单个页面的具体内容和逻辑承载者
- 一个Page Ability可管理多个AbilitySlice的导航栈(类似Android的Activity和Fragment关系)
三、架构设计原则
1. 分离关注点
- UI类应仅包含处理界面和操作系统交互的逻辑
- 避免在UI类中编写所有代码,减少对UI组件的依赖
2. 通过数据模型驱动界面
- 推荐使用持久性数据模型驱动界面
- 优势:
- 系统销毁应用释放资源时,用户不会丢失数据
- 网络连接不稳定时,应用仍可继续工作
3. 单一数据源(SSOT)
- 为每种数据类型分配单一、权威、可靠的数据源
- 优势:
- 集中管理特定类型数据的所有更改
- 保护数据防止未授权修改
- 更易于跟踪数据更改,便于发现bug
4. 单向数据流(UDF)
四、分层架构设计
鸿蒙应用采用"三层架构+灵活扩展"的设计理念:
1. 产品定制层
- 定位:设备个性化实现
- 包含内容:
- 针对不同设备屏幕尺寸和交互方式定制的UI组件
- 不同设备的专属资源(图片、布局文件)
- 设备特定的编译配置和运行时参数
- 典型实践:
- 手机端:触摸交互优化的UI组件
- 智慧屏:遥控器适配的导航逻辑
- 车载设备:语音交互专属模块
2. 基础特性层
- 定位:核心功能抽象
- 设计原则:高内聚、低耦合
- 特性:
- 特性独立:每个特性完成独立业务功能
- 接口稳定:对外提供统一调用接口
- 灵活部署:支持按需部署到不同设备
- 部署形式:
- 需要单独部署的特性 → 编译为Feature类型HAP包
- 不需要单独部署的特性 → 编译为HAR或HSP包
3. 公共能力层
- 定位:通用功能下沉
- 包含内容:
- UI组件库:可复用的自定义UI组件
- 工具类:常用功能工具(网络请求、数据处理)
- 基础服务:跨模块共享的基础服务
- 实现形式:编译为HAR包(静态共享包)或HSP包(动态共享包)
五、模块化设计实践
模块包类型选择
包类型 | 部署方式 | 功能特性 | 典型应用场景 |
---|
Entry | 独立部署 | 包含UI和设备定制逻辑 | 各设备主入口模块 |
Feature | 独立部署 | 可独立运行的特性模块 | 可动态加载的功能插件 |
HAR | 作为依赖引用 | 静态共享功能 | 公共组件库、工具类 |
HSP | 作为依赖引用 | 动态共享功能 | 运行时动态加载的服务 |
多设备共包实践示例
document-app
├── default-entry/ # 通用Entry模块
│ ├── src/
│ └── resources/
│ ├── base/ # 通用资源
│ ├── phone/ # 手机端资源
│ └── tablet/ # 平板端资源
└── document-engine/ # 文档处理引擎,编译为Feature HAP
资源管理最佳实践
resources/
├── base/ # 通用资源
│ ├── strings/
│ ├── images/
│ └── layouts/
├── phone/ # 手机端专属资源
│ ├── images/
│ └── layouts/phone.xml
└── tv/ # 智慧屏专属资源
├── images/
└── layouts/tv.xml
六、FA与PA交互机制
调用方式
1. Ability调用方式
- 特点:拥有独立Ability生命周期,采用远端进程通信
- 适用场景:提供基本服务供多FA调用或服务在后台独立运行
- 实现接口:IRemoteObject.onRemoteRequest()
2. Internal Ability调用方式
- 特点:与FA共进程,采用内部函数调用方式通信
- 适用场景:对服务响应时延要求较高的场景
- 限制:不支持其他FA访问调用
- 实现接口:AceInternalAbility.AceInternalAbilityHandler.onRemoteRequest()
JS FA调用Java PA接口
FA端接口
FeatureAbility.callAbility(OBJECT)
:调用PA能力FeatureAbility.subscribeAbilityEvent(OBJECT, Function)
:订阅PA能力FeatureAbility.unsubscribeAbilityEvent(OBJECT)
:取消订阅PA能力
参数说明
参数名 | 类型 | 必填 | 说明 |
---|
bundleName | string | 是 | Ability的包名称,需与PA端匹配,区分大小写 |
abilityName | string | 是 | Ability名称,需与PA端匹配,区分大小写 |
messageCode | number | 是 | Ability操作码,与PA端约定 |
abilityType | number | 是 | 0: Ability方式; 1: Internal Ability方式 |
data | Object | 否 | 发送到Ability的数据 |
syncOption | number | 否 | 0:同步(默认); 1:异步(仅Internal Ability支持) |
七、代码示例
1. FA生命周期管理示例
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
}
onWindowStageCreate(windowStage) {
windowStage.loadContent("pages/index", (err, data) => {
});
}
onCall(want) {
return new MyParticleAbilityStub("service");
}
}
2. JS FA调用PA示例
const ABILITY_TYPE_EXTERNAL = 0;
const ABILITY_TYPE_INTERNAL = 1;
const ACTION_SYNC = 0;
const ACTION_ASYNC = 1;
const ACTION_MESSAGE_CODE_PLUS = 1001;
export default {
plus: async function() {
var actionData = {};
actionData.firstNum = 1024;
actionData.secondNum = 2048;
var action = {};
action.bundleName = 'com.example.hiaceservice';
action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';
action.messageCode = ACTION_MESSAGE_CODE_PLUS;
action.abilityType = ABILITY_TYPE_INTERNAL;
action.syncOption = ACTION_SYNC;
action.data = actionData;
let result = await FeatureAbility.callAbility(action);
console.log('计算结果: ' + result);
return result;
}
}
3. PA端实现示例
public class ComputeServiceAbility extends AceInternalAbility {
private static final String TAG = "ComputeServiceAbility";
private static final int ACTION_CODE_PLUS = 1001;
public ComputeServiceAbility() {
super("com.example.hiaceservice.ComputeServiceAbility");
}
@Override
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
switch (code) {
case ACTION_CODE_PLUS: {
String dataStr = data.readString();
JSONObject jsonObject = new JSONObject(dataStr);
int firstNum = jsonObject.getInt("firstNum");
int secondNum = jsonObject.getInt("secondNum");
int result = firstNum + secondNum;
reply.writeString(String.valueOf(result));
return true;
}
default:
return false;
}
}
}
4. 分布式任务调度示例
Intent intent = new Intent();
intent.setDeviceID("deviceID");
intent.setBundleName("com.example.bundle");
intent.setAbilityName("com.example.ParticleAbility");
connectAbility(intent, new AbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IAbilityConnection abilityConnection, int resultCode) {
if (resultCode == 0) {
IAbilityConnection proxy = abilityConnection;
}
}
});
Intent intent = new Intent();
intent.setDeviceID("deviceID");
intent.setBundleName("com.example.bundle");
intent.setAbilityName("com.example.FeatureAbility");
startAbility(intent);
5. 线程通信示例
import { emitter, TaskDispatcher } from '@ohos.base';
import { Request } from '../common/network/Request';
const UI_TASK_DISPATCHER = TaskDispatcher.getGlobalTaskDispatcher(TaskDispatcher.Priority.HIGH);
class UserViewModel {
private userId: string = '';
async fetchUserData() {
const backgroundTask: TaskDispatcher = TaskDispatcher.createBackgroundTaskDispatcher();
backgroundTask.asyncDispatch(() => {
const data = Request.fetch(`https://api.user.com/${this.userId}`);
emitter.emit('USER_DATA_LOADED', data);
});
}
setupEventListener() {
emitter.on('USER_DATA_LOADED', (data) => {
UI_TASK_DISPATCHER.asyncDispatch(() => {
this.userInfo = data;
AppStorage.setOrCreate('userName', data.name);
});
});
}
}
八、典型案例分析
1. 印象笔记鸿蒙原生版
- 核心特性:跨端接续功能,手机靠近平板实现无缝接续浏览或编辑
- 技术实现:利用FA的跨设备迁移能力,实现应用状态的无缝流转
- 用户体验:无需担心学习进程中断,提升学习连续性
2. 学习通鸿蒙原生版
- 核心特性:
- 直接调用系统相机拍照,支持对焦、变焦等功能
- 笔记支持AI朗读,网络中断也能继续收听
- 技术实现:调用系统服务能力,结合FA的UI展示与PA的后台处理
3. 粉笔鸿蒙原生版
- 核心特性:
- 课程内容跨端接续观看
- 接入统一扫码服务,简化课程访问流程
- 技术实现:利用鸿蒙意图框架和分布式任务调度能力
4. 宝宝巴士鸿蒙原生版
- 核心特性:
- 跨设备无缝切换,支持手机、折叠屏、平板等多设备
- 意图框架能力实现学习内容一键直达
- 服务卡片实时更新内容
- 技术实现:基于FA/PA架构的"一次开发,多端部署",结合鸿蒙服务卡片能力
九、技术趋势
- Stage模型逐渐成为主流:
- 从API 9开始引入,多个应用组件共享同一虚拟机
- 减少内存占用,提高复杂应用性能
- 支持卡片、输入法、快捷开关等更多扩展能力
- 分布式能力深化:
- 跨设备服务调用与数据同步更高效
- 能力组合更灵活,支持构建复杂业务场景
- 设备协同更智能,无缝流转体验提升
- 模块化设计优化:
- HAP、HAR、HSP包类型分工更明确
- 按需加载能力增强,应用性能优化
- 多端部署更便捷,开发效率提升
- 原生智能与AI融合:
- AI能力更深度集成,如智能推荐、语音交互
- 安全能力增强,如人脸活体检测
- 用户体验更个性化、智能化、