鸿蒙端H5容器化建设——JSB通讯机制建设

老婆出轨  金牌会员 | 2024-8-29 18:51:24 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 527|帖子 527|积分 1581

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的静态范例信息,进行范例推导并生成对象描述和内联缓存,加速运行时对字节码的表明执行;AOT(Ahead-of-Time)Compiler使用静态范例信息直接将字节码编译生成优化机器码,让应用启动即可运行高性能代码,提拔应用启动和运行性能。
APP包结构

APP由一个或多个HAP(Harmony 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侧提供调用函数。
  1. export const code = `
  2.   const JSBridgeMap = {};
  3.   let callID = 0;
  4.   
  5.   // 执行H5回调函数
  6.   function JSBridgeCallback (id, params) {
  7.     JSBridgeMap[id](params);
  8.     JSBridgeMap[id] = null;
  9.     delete JSBridgeMap[id];
  10.   }
  11.   // 在window中声明callNative方法供H5调用
  12.   window.ohosCallNative = {
  13.     callNative(method, params, callback) {
  14.       const id = callID++;
  15.       const paramsObj = {
  16.           callID: id,
  17.           data: params || null
  18.       }
  19.       JSBridgeMap[id] = callback || (() => {});
  20.       JSBridgeHandle.call(method, JSON.stringify(paramsObj));
  21.     }
  22.   }
  23. `;
复制代码
5.2 JS署理注入

通过Web组件的javaScriptProxy属性,将JSBridgeHandle对象注册到H5侧的window上,作为H5调用原生的通道。
  1. // JsBridge.ets
  2. export default class JsBridge {
  3.   controller: WebView.WebviewController;
  4.   constructor(controller: WebView.WebviewController) {
  5.     this.controller = controller;
  6.   }
  7.   /**
  8.    * 注入JavaScript对象到window对象中  
  9.    */
  10.   get javaScriptProxy(): JavaScriptItem {
  11.     return {
  12.       object: {
  13.         call: this.call
  14.       },
  15.       name: "JSBridgeHandle",
  16.       methodList: ['call'],
  17.       controller: this.controller
  18.     } as JavaScriptItem;
  19.   }
  20.   
  21.    initJsBridge(): void {
  22.     this.controller.runJavaScript(code);
  23.   }
  24. }
  25. // PageDemo.ets
  26. @Entry
  27. @Component
  28. struct PageDemo {
  29.   webController: WebView.WebviewController = new WebView.WebviewController();
  30.   private jsBridge: JSBridge = new JSBridge(this.webController);
  31.   build() {
  32.     Column() {
  33.       Web({
  34.         src: $rawfile('MainPage.html'),
  35.         controller: this.webController
  36.       })
  37.         .javaScriptAccess(true)
  38.         .javaScriptProxy(this.jsBridge.javaScriptProxy)
  39.         .onPageBegin(() => {
  40.           this.jsBridge.initJsBridge();
  41.         })
  42.         ...
  43.     }
  44.     ...
  45.   }
  46. }
  47. /**
  48. * javaScriptProxy object type.
  49. */
  50. export interface callType {
  51.   call: (func: string, params: string) => void
  52. }
  53. export interface JavaScriptItem {
  54.   object: callType,
  55.   name: string,
  56.   methodList: Array<string>,
  57.   controller: WebviewController
  58. }
复制代码
5.3 H5侧入口与回调

H5侧调用ohosCallNative对象中的callNative方法,通报func、params以及callback回调。在callNative中生存callback回调,并调用JSBridgeHandle的call方法。call方法作为H5调用原生侧接口的同一入口,在该方法中根据H5调用的方法名,匹配到对应的接口后调用,调用结束后通过this.callback()方法,将调用结果回传到H5。
  1. // JsBridge.ets
  2. export default class JsBridge {
  3.   /**
  4.    * 将ArkTS侧数据传递给call方法
  5.    */
  6.   call = (func: string, params: string): void => {
  7.     const paramsObject: ParamsItem = JSON.parse(params);
  8.     let result: Promise<string> = new Promise((resolve) => resolve(''));
  9.     switch (func) {
  10.       case 'funName':
  11.         result = "result from ArkTS";
  12.         break;
  13.       default:
  14.         break;
  15.     }
  16.     result.then((data: string) => {
  17.       this.callback(paramsObject?.callID, data);
  18.     })
  19.   }
  20.   /**
  21.    * 将ArkTS侧数据传递到H5
  22.    */
  23.   callback = (id: number, data: string): void => {
  24.     this.controller.runJavaScript(`JSBridgeCallback("${id}", ${JSON.stringify(data)})`);
  25.   }
  26. }
  27. /**
  28. * Function params object.
  29. */
  30. export interface ParamsItem {
  31.   callID: number
  32. }
复制代码
5.4 H5侧主动发起调用ArkTS

实现了上述桥接逻辑后,在H5侧只必要调用ohosCallNative方法,将函数名以及回调函数通报到ArkTS。
  1.   window.ohosCallNative.callNative('funName', {}, (data) => {
  2.     ...
  3.   });
复制代码
6. 总结

本文概述了鸿蒙系统的架构以及开发模式,并且指出鸿蒙的适配工作任重而道远。此中,Native侧的迁移适配必要大量的时间和成本;而H5作为自然的跨端生态,尤其是在业务中原来就有很重的业务承载,那么H5容器化是起主要去适配的。ArkTS与H5的JSB通讯机制则是本文的重点描述内容,剩下的H5容器所需的Native本领,则必要一点一点去补齐。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表