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

news2024/11/25 16:39:43

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1321206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NVMe over CXL技术如何加速Host与SSD数据传输?

在现代计算环境中&#xff0c;优化Host&#xff08;主机&#xff09;与device&#xff08;设备&#xff09;之间的数据传输速度对于提升系统整体性能和效率至关重要。目前业内主要有以下几种方案&#xff1a; Controller Memory Buffer (CMB)&#xff1a; CMB是一种集成在NVMe …

Python数据科学视频讲解:Python数据缺失值处理

3.5 Python数据缺失值处理 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解3.5节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据…

数据库增删改查Native SQL

DBCO&#xff1a;检查数据库是否连接 代码&#xff1a; 查询&#xff1a; DATA: gv_dbs TYPE char30 VALUE XXXXXXXX. "数据库连接名称 DATA:gt_ztclaim_2 TYPE TABLE OF ztclaim_2. DATA:gs_ztclaim_2 TYPE ztclaim_2.TRY.EXEC SQL.CONNECT TO :GV_DBSENDEXEC.EXEC SQ…

【计算机网络】TCP协议——2.连接管理(三次握手,四次挥手)

目录 前言 一. 建立连接——三次握手 1. 三次握手过程描述 2. TCP连接建立相关问题 二. 释放连接——四次挥手 1. 四次挥手过程描述 2. TCP连接释放相关问题 三. TCP状态转换 结束语 前言 TCP——传输控制协议(Transmission Control Protocol)。是一种面向连接的传…

弹幕情感分析可视化

弹幕情感分析可视化 引言1. 弹幕数据爬取2. 弹幕数据处理3. 弹幕数据可视化4. 弹幕情感分析5. 创新点&#xff1a;弹幕情感倾向分布 引言 当今互联网时代&#xff0c;大量的弹幕数据蕴含着丰富的信息&#xff0c;通过对这些数据进行分析和可视化&#xff0c;我们能够深入了解用…

【01】GeoScene生产海图或者电子航道图

1.1 什么是电子海图制图模块 GeoScene海事模块是一个用于管理和制作符合国际水文组织&#xff08;IHO&#xff09;S-100系列标准和S-57标准的海事数据的系统。提供了S-100和S-57工具&#xff0c;用于加载基于S-100的要素目录、创建基于S-57传输结构的数据、输入数据、符号化数…

U-Net 算法详解

目录 1.任务概述 2.编码器-解码器 3.跳跃连接 4.实现细节 5.损失函数 6.上采样方法 不填充还是填充&#xff1f; 7.U-Net 的运作方式 8.结论 1.任务概述 U-Net 是为语义分割任务开发的。当神经网络接受图像作为输入时&#xff0c;我们可以选择一般性地分类对象或按实例…

传统软件集成AI大模型——Function Calling

传统软件和AI大模型的胶水——Function Calling 浅谈GPT对传统软件的影响Function Calling做了什么&#xff0c;为什么选择Function CallingFunction Calling简单例子&#xff0c;如何使用使用场景 浅谈GPT对传统软件的影响 目前为止好多人对chatGPT的使用才停留在OpenAI自己提…

【Linux】sed命令使用

sed 命令 sed全称是&#xff1a;Stream EDitor。 sed 命令是利用脚本来处理文本文件。sed 一次只读取一行文本到缓冲区&#xff0c;然后读取命令&#xff0c;对此行进行编辑&#xff0c;然后读取下一行&#xff0c;重复此过程直到结束。 sed 与 vi 的区别 【Linux】 vi / v…

【DOM笔记二】操作元素(修改元素内容,修改常见元素/表单元素/元素样式属性,排他思想,自定义属性操作,应用案例!)

文章目录 4 操作元素4.1 修改元素的内容4.2 修改常见元素的属性案例&#xff1a;分时问候 4.3 修改表单元素属性案例&#xff1a;登录时隐藏/显示密码 4.4 修改元素样式属性4.4.1 行内样式操作 element.style案例1&#xff1a;关闭二维码广告案例2&#xff1a;遍历精灵图案例3&…

C# 图解教程 第5版 —— 第19章 枚举器和迭代器

文章目录 19.1 枚举器和可枚举类型19.2 IEnumerator 接口19.3 IEnumerable 接口19.4 泛型枚举接口19.5 迭代器19.5.1 迭代器块19.5.2 使用迭代器来创建枚举器19.5.3 使用迭代器来创建可枚举类型 19.6 常见迭代器模式19.7 产生多个可枚举类型19.8 将迭代器作为属性19.9 迭代器的…

Postman使用总结--参数化

将 测试数据&#xff0c;组织到 数据文件中&#xff0c;通过脚本的反复迭代&#xff0c;使用不同的数据&#xff0c;达到测试不同用例的目标 数据文件有两种&#xff1a; CSV &#xff08;类似于excel&#xff09; 格式简单用这个 文件小 JSON&#xff08;字典列表&#x…

Vue3-22-组件-插槽的使用详解

插槽是干啥的 插槽 就是 组件中的一个 占位符&#xff0c; 这个占位符 可以接收 父组件 传递过来的 html 的模板值&#xff0c;然后进行填充渲染。 就这么简单&#xff0c;插槽就是干这个的。要说它的优点吧&#xff0c;基本上就是可以使子组件的内容可以被父组件控制&#xf…

Amazon CodeWhisperer 体验

文章作者&#xff1a;jiangbei 1. CodeWhisperer 安装 1.1 先安装 IDEA&#xff0c;如下图&#xff0c;IDEA2022 安装为例&#xff1a; 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者…

MongoDB中的关系

本文主要介绍MongoDB中的关系。 目录 MongoDB的关系嵌入关系引用关系 MongoDB的关系 MongoDB是一个非关系型数据库&#xff0c;它使用了键值对的方式来存储数据。因此&#xff0c;MongoDB没有像传统关系型数据库中那样的表、行和列的概念。相反&#xff0c;MongoDB中的关系是通…

主馆位置即将售罄“2024北京国际信息通信展会”众多知名企聚京城

2024北京国际信息通信展&#xff0c;将于2024年9月份在北京国家会议中心盛大召开。作为全球信息通信技术领域的重要盛会&#xff0c;此次展会将汇集业内顶尖企业&#xff0c;展示最新的技术成果和产品。 目前&#xff0c;主馆位置即将售罄&#xff0c;华为、浪潮、中国移动、通…

数据结构(Chapter Two -02)—顺序表基本操作实现

在前一部分我们了解线性表和顺序表概念&#xff0c;如果有不清楚可以参考下面的博客&#xff1a; 数据结构(Chapter Two -01)—线性表及顺序表-CSDN博客 首先列出线性表的数据结构&#xff1a; #define MaxSize 50 //定义顺序表最大长度 typedef struct{ElemType data…

【面试】Java最新面试题资深开发-微服务篇(1)

问题九&#xff1a;微服务 什么是微服务架构&#xff1f;它与单体架构相比有哪些优势和劣势&#xff1f;解释一下服务发现和服务注册是什么&#xff0c;它们在微服务中的作用是什么&#xff1f;什么是API网关&#xff08;API Gateway&#xff09;&#xff1f;在微服务中它有何…

什么是关键词排名蚂蚁SEO

关键词排名是指通过搜索引擎优化&#xff08;SEO&#xff09;技术&#xff0c;将特定的关键词与网站相关联&#xff0c;从而提高网站在搜索引擎中的排名。关键词排名对于网站的流量和用户转化率具有至关重要的影响&#xff0c;因此它是SEO工作中最核心的部分之一。 如何联系蚂…

任务十六:主备备份型防火墙双机热备

目录 目的 器材 拓扑 步骤 一、基本配置 配置各路由器接口的IP地址【省略】 1、配置BGP协议实现Internet路由器之间互联 2、防火墙FW1和FW2接口IP配置与区域划分 3、配置区域间转发策略 4、配置NAPT和默认路由 5、配置VRRP组&#xff0c;并加入Active/standby VGMP管…