恒峰网站建设问题,百度登录入口官网,互联网行业发展前景分析报告,广点通1. 背景
2023年鸿蒙开发者大会上#xff0c;华为宣布为了应对国外技术封锁的潜在风险#xff0c;2024年的HarmonyOS NEXT版本中将不再兼容Android#xff0c;并推出鸿蒙系统以及其自研的开发框架#xff0c;形成开发生态闭环。同时#xff0c;在更高维度上华为希望将鸿蒙…1. 背景
2023年鸿蒙开发者大会上华为宣布为了应对国外技术封锁的潜在风险2024年的HarmonyOS NEXT版本中将不再兼容Android并推出鸿蒙系统以及其自研的开发框架形成开发生态闭环。同时在更高维度上华为希望将鸿蒙系统拓展应用到手机、智能穿戴、车机、家居等一系列物联网设备上形成万物互联的品牌生态闭环。
基于以上背景鸿蒙端上APP的适配问题是开发者不得不面对的问题适配也将从原生和跨端两个方面进行。鸿蒙原生ArkTs包含的内容可以对标Android原生既多又杂可以参考官方文档跨端则涉及H5、RN、Flutter的鸿蒙化适配。由于目前产品的跨端重心在H5因此本文将主要介绍鸿蒙端H5容器化的适配工作同时简述鸿蒙系统框架以及开发模式。
2. 鸿蒙系统架构 HarmonyOS整体遵从分层设计从下向上依次为内核层、系统服务层、框架层和应用层。可以看出已经了抛离AOSP和JVM去除了对Android依赖。
内核层
采用多内核设计提供进程/线程管理、内存管理、文件系统、网络管理和外设管理等基础内核能力。驱动子系统HDF提供统一外设访问能力和驱动开发管理框架。
系统服务层
包括适用于各类设备的基础能力以及面向特定设备的专有能力每个子系统内部支持按功能粒度裁剪。
框架层
为应用开发提供Java/C/C/JS等多语言的用户程序框架以及各种软硬件服务对外开放的多语言框架API。
应用层
支持基于框架层实现业务功能开发支持跨设备调度与分发为用户提供一致、高效的应用体验。
3. 鸿蒙开发模式
开发工具DevEco-Studio
开发工具下载地址HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者和Android Studio的功能和设计大体一致工程结构也有诸多相似之处。但是仅处于起步阶段各种问题还需要完善和解决诸如模拟器H5页面无法交互、以及各种调试问题等。
开发语言与UI框架
ArkTs是华为基于TypeScript的自研开发语言。ArkUI 是一套声明式开发框架它具备简洁自然的 UI 信息语法、丰富的 UI 组件、多维状态管理以及实时多维度预览等能力只需使用一套ArkTS API就能在多个HarmonyOS设备上提供生动而流畅的用户界面体验帮助开发者提升应用开发效率。
编译模式
ArkCompiler利用ArkTS的静态类型信息进行类型推导并生成对象描述和内联缓存加速运行时对字节码的解释执行AOTAhead-of-TimeCompiler利用静态类型信息直接将字节码编译生成优化机器码让应用启动即可运行高性能代码提升应用启动和运行性能。
APP包结构
APP由一个或多个HAPHarmony Ability Package包以及描述APP属性的pack.info文件组成。HAP是Abiltiy类型的模块编译后的产物而Library类型的模块编译后的产物为HAR静态共享包或者HSP动态共享包两者都是为了实现代码和资源的共享。HAR中的代码和资源跟随使用方编译多个使用方会存在多份拷贝而HSP中的代码和资源可以独立编译运行时在同一进程中仅有一份从而避免包膨胀问题。
4. 适配工作
原生业务
目前项目中Native原始业务与H5跨端业务并存基于Native的业务在新的鸿蒙系统上将无法运行为了兼顾用户体验问题只能使用ArkTS进行重写。这将是一个繁杂且漫长的适配工程需要明确App核心功能在初期版本上优先适配核心业务能力。
H5业务
鸿蒙提供了H5页面运行所需的Web容器H5页面是可以百分百复用的。但是H5侧依赖Native能力的各种API需要额外做定制和适配从而实现真正的H5容器化SDK这将是优先级极高的适配工作。其中H5与Native之间的通信机制建设则是重中之重的适配内容。
5. H5容器化建设——JSB通信机制建设
ArkTS侧与H5的通信机制是首先要解决的问题有了JSB的桥才有后续Native能力支撑的可能。JSB通信总体可以分为四个步骤来进行
5.1 JSBridge初始化
在初始化阶段需要通过webviewControll.runJavaScript()将JSBridge初始化脚本注入H5执行。脚本代码如下所示。其中callID用来标识H5回调JSBridgeCallback方法用来执行H5侧回调window.ohosCallNative对象给H5侧提供调用函数。
export const code const JSBridgeMap {};let callID 0;// 执行H5回调函数function JSBridgeCallback (id, params) {JSBridgeMap[id](params);JSBridgeMap[id] null;delete JSBridgeMap[id];}// 在window中声明callNative方法供H5调用window.ohosCallNative {callNative(method, params, callback) {const id callID;const paramsObj {callID: id,data: params || null}JSBridgeMap[id] callback || (() {});JSBridgeHandle.call(method, JSON.stringify(paramsObj));}}
;5.2 JS代理注入
通过Web组件的javaScriptProxy属性将JSBridgeHandle对象注册到H5侧的window上作为H5调用原生的通道。
// JsBridge.ets
export default class JsBridge {controller: WebView.WebviewController;constructor(controller: WebView.WebviewController) {this.controller controller;}/*** 注入JavaScript对象到window对象中 */get javaScriptProxy(): JavaScriptItem {return {object: {call: this.call},name: JSBridgeHandle,methodList: [call],controller: this.controller} as JavaScriptItem;}initJsBridge(): void {this.controller.runJavaScript(code);}
}// PageDemo.ets
Entry
Component
struct PageDemo {webController: WebView.WebviewController new WebView.WebviewController();private jsBridge: JSBridge new JSBridge(this.webController);build() {Column() {Web({src: $rawfile(MainPage.html),controller: this.webController}).javaScriptAccess(true).javaScriptProxy(this.jsBridge.javaScriptProxy).onPageBegin(() {this.jsBridge.initJsBridge();})...}...}
}/*** javaScriptProxy object type.*/
export interface callType {call: (func: string, params: string) void
}export interface JavaScriptItem {object: callType,name: string,methodList: Arraystring,controller: WebviewController
}5.3 H5侧入口与回调
H5侧调用ohosCallNative对象中的callNative方法传递func、params以及callback回调。在callNative中保存callback回调并调用JSBridgeHandle的call方法。call方法作为H5调用原生侧接口的统一入口在该方法中根据H5调用的方法名匹配到对应的接口后调用调用结束后通过this.callback()方法将调用结果回传到H5。
// JsBridge.ets
export default class JsBridge {/*** 将ArkTS侧数据传递给call方法*/call (func: string, params: string): void {const paramsObject: ParamsItem JSON.parse(params);let result: Promisestring new Promise((resolve) resolve());switch (func) {case funName:result result from ArkTS;break;default:break;}result.then((data: string) {this.callback(paramsObject?.callID, data);})}/*** 将ArkTS侧数据传递到H5*/callback (id: number, data: string): void {this.controller.runJavaScript(JSBridgeCallback(${id}, ${JSON.stringify(data)}));}
}/*** Function params object.*/
export interface ParamsItem {callID: number
}5.4 H5侧主动发起调用ArkTS
实现了上述桥接逻辑后在H5侧只需要调用ohosCallNative方法将函数名以及回调函数传递到ArkTS。 window.ohosCallNative.callNative(funName, {}, (data) {...});6. 总结
本文概述了鸿蒙系统的架构以及开发模式并且指出鸿蒙的适配工作任重而道远。其中Native侧的迁移适配需要大量的时间和成本而H5作为天然的跨端生态尤其是在业务中本来就有很重的业务承载那么H5容器化是首先要去适配的。ArkTS与H5的JSB通信机制则是本文的重点描述内容剩下的H5容器所需的Native能力则需要一点一点去补齐。