拍拍贷鸿蒙版H5容器之路

news2024/10/28 23:38:15

背景介绍

业务背景

2024年1月18日华为宣布:HarmonyOS NEXT 将不再支持 Android系统,基于以上背景及国内信贷业务现状,公司决定启动借款App鸿蒙化项目。

下图是2024年6月华为HDC大会上,华为宣布 HarmonyOS NEXT 将面向开发者和先锋用户启动Beta升级,并计划在今年四季度正式商用。

技术背景

借款APP业务层约70%是基于H5页面构建的,经过多年的迭代,Android与iOS已经有一个非常稳定和强大的Web组件,即:PPDWebUI。为了避免业务层过多地适配,加快App鸿蒙化进程,在技术上只需要开发一个鸿蒙版的PPDWebUI,功能和Android、iOS保持一致,就可以承接已有业务。最终使得业务站点改动的成本最小,并且实现了三端技术架构的统一。

下面的内容主要是介绍我们实现PPDWebUI的方案和实现过程中遇到的困难与挑战。

方案设计

如上图,方案的思路是基于鸿蒙官方提供的ArkWeb进行封装,实现鸿蒙PPDWebUI组件

  • ArkWeb简介:鸿蒙官方提供的基于谷歌Chromium内核的Web组件,使用的Chromium版本为M114(截止本文编写时)

PPDWebUI组件分为两部分

  • Web容器,提供H5容器和原生服务
  • ppdwebui.js,负责JS与Native的通信,本质上是对JsBrdige的封装

PPDWebUI组件的Web容器

  • 原生和H5交互原理
  1. 使用JsBridge通信通过javaScriptProxy和runJavaScript来实现JsBridge。使用javaScriptProxy将原生侧接口注入到H5的window对象上,通过runJavaScript接口执行JS脚本到H5中,并在回调中获取脚本执行结果。
  • 调用流程如下图所示:

  •  代码示例:
Web({      src: this.url ?? '',      controller: this.webviewController      }).javaScriptProxy({      // 将对象注入到web      object: this.jsApi,      name: "_foo",      methodList: ["bar"],      controller: this.webviewController      }
  • 注入原生服务不采用开始加载页面的时候就注入原生服务的原因:
  • 减少不必要的注入,每次注入原生服务都需要依赖于站点应用引用的js。
  • 更安全可控,每次注入原生服务的时候都可以进行安全校验。通过ArkWeb中的onInterceptRequest方法拦截js替换本地WebUI.js,同时注入原生的插件方法名称,让其挂载在容器上,这样H5就可以调用原生方法,拦截注入代码如下:
onInterceptRequest(event?: InterceptEvent): WebResourceResponse | null {      let url: string = event?.request?.getRequestUrl() as string;      if (url.match(/^https?:\/\/xxx\.xxx\.com\/[\d.]+\/xxx\.js$/)) {        let webResp = new WebResourceResponse();        const resourceMgr: resourceManager.ResourceManager = this.context.resourceManager;        let js = buffer.from(resourceMgr.getRawFileContentSync('xxx1.0.js')).toString('utf-8')        let respData =          `${js};window.PPDWebUI && window.PPDWebUI.initJSConfig && window.PPDWebUI.initJSConfig(${this.appendJsStr})`        webResp.setResponseData(respData);        webResp.setResponseCode(200)        webResp.setResponseEncoding('utf-8')        webResp.setResponseMimeType('application/javascript')        webResp.setResponseIsReady(true)        return webResp      } else {        return null      }    }

  • PPDWebUI容器使用
  1. 容器初始化
// 页面即将显示的时候注册服务aboutToAppear(): void
 {  PPDWebUIInitManager.registerService(new LoanServiceCaller());}//自定义WebUI组件初始化WebUI({    webUrl: this.webUrl,    props: this.webuiPro,    webClient: new WebClientImp(getContext(this)),    webUIConfig: new WebUIConfig(this.appendUserAgent,true),    webUIHostController: this.webUIHostController})  .layoutWeight(1)  .width('100%')
  • H5业务的适配
    1. 升级WebUI.js:所有业务的H5页面均使用统一提供的PPDWebUI.js调用Native的原生能力,H5页面仅需要对 PPDWebUI.js 进行升级,即可以运行在鸿蒙系统上,无需其他特殊适配逻辑。
    2. 如有需要针对操作系统的特殊需求,页面可依据Native注入的系统信息来识别当前运行的操作系统,简单高效。

困难与挑战

下面列举了我们在实现鸿蒙版PPDWebUI组件时遇到的问题与解决方案,供大家参考

  1. H5页面与原生容器如何联调?
  • ArkWeb组件支持使用DevTools工具调试前端页面,开发者需通过setWebDebuggingAccess()接口开启Web组件前端页面调试能力,利用DevTools工具可以在电脑上调试移动设备上的前端网页
  • 使用DevTools工具,可以执行以下步骤:
  • 在应用代码中开启Web调试开关,具体如下:
aboutToAppear() {    // 配置Web开启调试模式    webview.WebviewController.setWebDebuggingAccess(true);  }  build() {    Column() {      Web({ src: 'www.example.com', controller: this.controller })    }  }}

开启调试功能需要在DevEco Studio应用工程hap模块的module.json5文件中增加如下权限,添加方法请参考在配置文件中声明权限。

"requestPermissions":[   {     "name" : "ohos.permission.INTERNET"   } ]

将设备连接上电脑,在电脑端配置端口映射,配置方法如下:

//查找 devtools 远程调试所需的 domain socket 名称,该名称与进程号有关,重启调试应用后,需要重复此步骤,以完成端口转发cat /proc/net/unix | grep devtools// 添加映射 [pid] 替换成实际的进程idhdc fport tcp:9222 localabstract:webview_devtools_remote_[pid]// 查看映射 hdc fport ls示例:hdc shellcat /proc/net/unix | grep devtoolsexithdc fport tcp:9222 localabstract:webview_devtools_remote_3458hdc fport ls

在电脑端Chrome浏览器地址栏中输入chrome://inspect/#devices,页面识别到设备后,就可以开始页面调试。调试效果如下:

2. 导航栏标题不显示或显示不对问题?

  • 通过H5容器的ArkWeb的原生onTitleReceive方法获取H5的docment.title,设置导航标题
  Web(...)   .onTitleReceive((event) => {        this.props.navTitle = event.title; })

  3. H5页面需支持侧滑返回上一次H5页面问题?

  • 通过H5容器的ArkWeb的原生onBackPressed方法监听返回键,拦截返回动作,实现H5页面的侧滑返回上一页。

  4. 同一个webview中,先打开A页面,然后setTimeout 2秒 后使用location.href跳转B页面。B页面没有触发webview的任何事件问题?

  • 原因是调用setCustomUserAgent后与web页面的跳转时序相关,Web跳转后才设置UserAgent,这就导致页面跳转了但新UserAgent关联的页面堆栈数仍只有一个WebView

  5. 多个JsBridge注入问题?

  • 无法使用 javaScriptProxy 方法注入多个 JsBridg对象,需要在生命周期方法 onControllerAttached() 中 调用 WebViewController 的 registerJavaScriptProxy() 方法注入 JsBridg对象
  Web(...)    .onControllerAttached(() => {    this.webviewController.registerJavaScriptProxy(...)      })

未来规划

  • 在业务迭代过程中,为进一步抹平三端差异,计划将Android/iOS离线包方案也移植到鸿蒙版借款App中,提升H5的用户体验
  • 性能优化,开发过程中,也面临ArkWeb加载和丢帧等问题,目前了解到DevEco Profiler提供ArkWeb分析模板,后面也会结合ArkWeb执行流程的关键trace点,来定位问题发生的阶段,并做一些针对性的性能优化
     

作者简介

Jsiguo,信也科技移动研发资深专家

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

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

相关文章

Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置

文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1,添加2811路由器。 2,添加pc0。 3,使用交叉线连接路由器和pc(注意线路端口)。 4,使用配置线连接路由器和pc(注意线路…

IT监控对接华三CAS云管平台监控方案

概述 CAS云管平台是新华三集团自主研发的虚拟化和云计算管理平台,它主要面向数据中心,提供虚拟化和云计算管理,在教育行业、网络安全领域、高性能计算业务、企业IT部门等领域被广泛应用。在信创国产化背景下,以CAS、Fusion等为代…

rtp协议:rtcp包格式和传输间隔

RTP Control Protocol -- RTCP-rtp控制协议 实时传输控制协议(RTCP)基于对会话中的所有参与者定期传输控制包,使用与数据包相同的分发机制。底层协议必须提供数据包和控制包的多路复用,例如使用UDP时使用不同的端口号。RTCP执行四…

LLMs 入门实战系列大全:LLMs应用、领域大模型介绍、大模型常见面经汇总

1. 常见大模型介绍 1.1 ChatGLM-6B 系列 ChatGLM2-6B [【ChatGLM2-6B 入门】清华大学开源中文版 ChatGLM-6B 模型学习与实战] 更强大的性能:基于 ChatGLM 初代模型的开发经验,我们全面升级了 ChatGLM2-6B 的基座模型。ChatGLM2-6B 使用了 GLM 的混合目…

sa-token 所有的异常都是未登录异常的问题

在使用satoken的时候,有这么一个问题,就是不管我是什么错误,都会弹出未登录异常,起初的时候我以为satoken的拦截器会拦截所有的异常,但是今后测试才发现忽略了一点,也是最重要最容易忽视的一点。 如果我现在…

动态规划 —— 路径问题-不同路径

1. 不同路径 题目链接: 62. 不同路径 - 力扣(LeetCode)https://leetcode.cn/problems/unique-paths/description/ 2. 算法原理 1. 状态表示:以莫一个位置为结尾 dp[i]表示:以[i,j]位置为结尾时&#xff0…

新手入门c++(8)

到时候了,是时候给你们讲一下其他的定义形式与格式化输入输出了。 1.长整型变量 长整型变量分为两种: ①long类型 在计算机编程中,long 类型是一个整型数据类型,用于存储较大的整数。它的大小和范围取决于操作系统和编译器的实…

存储引用服务(OSS)Minio 环境搭建

下载Docker desktop 最好进行相关的设置,比如说进行登陆docker账号等等 推荐使用 docker-engine源【目前还能使用下载】 https://ccr.ccs.tencentyun.com 使用docker拉取对应的minio镜像 netstat -aon|findstr "8081" 注意:dockerhub有时…

QT访问数据库:应用提示Driver not loaded

在QT中运行完全正确错误截图 解决办法 我用的是MySQL。我把libmysql.dll复制到应用程序的目录下,即可正常访问数据库。

Hugging Face 使用指南——并行智算云(10s上手版)

1. 在bash中使用 1.1 直接复制命令 echo export HF_ENDPOINT"https://hf-mirror.com" >> ~/.bashrc # 在bashrc文件中设置镜像地址 source ~/.bashrc # 使修改立即生效 echo $HF_ENDPOINT # 查看是否成功红框部分出现就是正确了 1.2 命令详解 命令行echo…

HarmonyOS开发 - 本地持久化之实现LocalStorage支持多实例

用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。 在上一篇中&…

CodeQL学习笔记(1)-QL语法(逻辑连接词、量词、聚合词、谓词和类)

最近在学习CodeQL,对于CodeQL就不介绍了,目前网上一搜一大把。本系列是学习CodeQL的个人学习笔记,根据个人知识库笔记修改整理而来的,分享出来共同学习。个人觉得QL的语法比较反人类,至少与目前主流的这些OOP语言相比&…

计算机视觉专栏(2)【LeNet】代码实战【pytorch】完整可运行

LeNet 系列 实践部分1.引言2. limu代码3. plpal代码3.1 代码调试3.2 代码详解 4. 总结 实践部分 Lenet的实现分为两种代码,一种是李沐老师的实现代码以及b友up霹雳啪啦的代码,两者都有不同的优点,李老师的lenet十分还原原著中的操作&#xf…

ios 项目升级极光SDK

由于项目使用的是旧版本,隐私合规检查不通过,需要升级到最新版本, 使用cocoapods集成无法正常运行,.a文件找不到,可能项目比较久了,最好选择手动导入 下载最新版本SDK,将 SDK 包解压&#xff…

IROS 2024最新接收的Motion Planning前沿研究成果汇总

No.1 文章标题:Extended Tree Search for Robot Task and Motion Planning 作者:REN, Tianyu; Chalvatzaki, Georgia; Peters, Jan 中文标题:机器人任务和运动规划的扩展树搜索 No.2 文章标题:Kinodynamic Motion Planning fo…

Jmeter分布式性能测试细节+常见问题解决

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 Jmeter分布式测试时需要的特别注意 1)参数化文件的位置和内容 如果使用csv文件进行参数化,即通过读取csv文件中的数据来为测试脚本提供…

C/C++每日一练:实现选择排序

选择排序 选择排序是一种简单直观的排序算法,时间复杂度为,其中 n 是数组长度,不适合大数据集的排序,适合于元素较少且对性能要求不高的场景。 选择排序的基本思想是:每次从未排序部分选择最小的元素,将其放…

[四轴飞行器] 遥控器操作说明

遥控器操作说明 1 A:无线连接信号强度:已连接 B:控制模式:H定高模式,T定点模式 C:遥控器状态:加锁 D:飞行模式:无头 E:电量显示:遥控器电量(加…

OpenCV系列教程六:信用卡数字识别、人脸检测、车牌/答题卡识别、OCR

文章目录 一、信用卡数字识别1.1 模板匹配1.2 匹配多个对象1.3 处理数字模板1.4 预处理卡片信息,得到4组数字块。1.5 遍历数字块,将卡片中每个数字与模板数字进行匹配 二、人脸检测2.1人脸检测算法原理2.2 OpenCV中的人脸检测流程 三、车牌识别3.1 安装t…

Jupyter Notebook 中使用render_notebook渲染pyecharts图像不显示的一种情况

一开始我发现自己的jupyter文件在渲染pyecharts图片时一开始可以显示,但后来不知道怎么的就不显示了,查找了很多方法,但是没有效果,都是改js渲染什么的,还有就是参数不对的,对于我来说都没什么用&#xff0…