鸿蒙官方推荐使用 JS 或 eTS 方式来开发 APP 应用 UI,但在开发过程中有可能会遇到 JS UI 无法实现的功能,例如地图导航、定制化视频播放器。
那么这种场景下如何实现功能,这个需求就带来如下问题:
一个页面是否能同时使用 JavaUI 和 JSUI,JSUI 来实现简单功能,JavaUI 来实现定制化功能
一个工程是否支持不同的 UI 语法,比如 PageA 使用 JSUI,PageB 使用 JavaUI
Java UI
使用 xml 方式描述 UI 界面布局,应用中所有的用户界面元素都是由 Component 和 ComponentContainer 对象构成。
Component 是绘制在屏幕上的一个对象,用户能与之交互。ComponentContainer 是一个用于容纳其他 Component 和 ComponentContainer 对象的容器。
Java UI 框架提供了一部分 Component 和 ComponentContainer 的具体子类,即创建用户界面(UI)的各类组件。
包括一些常用的组件(比如:文本、按钮、图片、列表等)和常用的布局(比如:Directional
layout 和 DependentLayout)。用户可通过组件进行交互操作,并获得响应。
JS UI
基于 JS 扩展的类
Web 开发范式的方舟开发框架是一种跨设备的高性能 UI 开发框架,支持声明式编程和跨设备多态 UI。
采用类 HTML 和 CSS Web 编程语言作为页面布局和页面样式的开发语言,页面业务逻辑则支持 ECMAScript 规范的 JavaScript 语言。
方舟开发框架提供的类 Web 编程范式,可以让开发者避免编写 UI 状态切换的代码,视图配置信息更加直观。
eTS UI
使用基于 TS 扩展的声明式开发范式的方舟开发框架,采用更接近自然语义的编程方式,让开发者可以直观地描述 UI 界面,不必关心框架如何实现 UI 绘制和渲染,实现极简高效开发。
从组件、动效和状态管理三个维度来提供 UI 能力,还提供了系统能力接口,实现系统能力的极简调用。
根据 Ability 的分类来考虑,JsUI 继承自 AceAbility,而 JavaUI 使用 xml 方式进行渲染,它继承自 Ability。
所以在同一界面上使用两个语言在页面渲染器就已经决定了,JavaUI 和 JSUI 不能在同一 Page 中使用。
那么问题 2 是否可行呢,答案是可以的。因为 PageA 和 PageB 可以用 2 个不同的 Ability 来渲染实现。
需要实现 PageA 是应用主页面,使用 JSUI 实现,PageA 上有个按钮跳转到 PageB,PageB 展示地图导航页面,PageB 使用 JavaUI 实现。
JSUI 自带有 router 功能,可以通过 router.push 进行跳转,但这仅限于 JSUI 的不通页面,对于上述场景行不通。
那么只能使用 ability 的 startAbility 能力来实现不同 ability 之前的跳转。
使用 AceInternalAbility 来接收页面的跳转请求,然后通过 ability 的 startAbility 方法跳转到另一个 ability。
流程图如下:
代码实现
MainAbility.java:
@Override
public void onStart(Intent intent) {
……
// 注册AceInternalAbility,接收首页按钮请求
TransInternalAbility.getInstance().register(this);
super.onStart(intent);
}
}
TransInternalAbility.java:
private static final String BUNDLE_NAME = "cn.pmagroup.ble.pmap30";
private static final String MAP_ABILITY_NAME = "cn.pmagroup.ble.pmap30.ability.MapAbility";
private static final String ABILITY_NAME = "cn.pmagroup.ble.pmap30.ability.TransInternalAbility";
private static final int SUCCESS = 0;
private static final int ERROR = 1;
private static final int PULL_MAP_PAGE = 1001;
// 定义日志标签
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");
private static TransInternalAbility instance;
private Ability ability;
private TransInternalAbility() {
super(BUNDLE_NAME, ABILITY_NAME);
}
public static TransInternalAbility getInstance() {
if (instance == null) {
synchronized (TransInternalAbility.class) {
if (instance == null) {
instance = new TransInternalAbility();
}
}
}
return instance;
}
public static void register(Ability ability) {
HiLog.info(LABEL, "DataHandlerAbility: register");
if (ability == null) {
HiLog.info(LABEL, "register abilityContext is null");
} else {
HiLog.info(LABEL, "register " + ability.getBundleName());
if (instance == null) {
instance = new TransInternalAbility();
}
instance.onRegister(ability);
}
}
/**
* init Internal ability
*/
public void onRegister(Ability ability) {
this.ability = ability;
this.
SETinternalAbilityHandler(this:

nRemoteRequest);
}
private boolean onRemoteRequest(int code,
messageParcel data, MessageParcel reply, MessageOption option) {
HiLog.info(LABEL, "DataHandlerAbility: onRemoteRequest");
String dataString = data.readString();
switch (code) {
case PULL_MAP_PAGE: {
reply.writeString("{ code: 0 }");
// 拉起地图导航JavaUI ability
this.pullMapPage();
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
// 拉起地图导航JavaUI ability
private void pullMapPage() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withBundleName(BUNDLE_NAME)
.withAbilityName(MAP_ABILITY_NAME).build();
intent.setOperation(operation);
this.ability.startAbilityForResult(intent, PULL_MAP_PAGE);
}
}
.......
更多详细内容请下载附件查看