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

2023-12-19 01:44

本文主要是介绍鸿蒙端H5容器化建设——JSB通信机制建设,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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侧提供调用函数。

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: Array<string>,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: Promise<string> = 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能力,则需要一点一点去补齐。

这篇关于鸿蒙端H5容器化建设——JSB通信机制建设的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/510492

相关文章

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF