当前位置: 首页 > news >正文

拍拍贷鸿蒙版H5容器之路

背景介绍

业务背景

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.mrgr.cn/news/60397.html

相关文章:

  • 纯GO语言开发RTSP流媒体服务器-RTSP推流直播、本地保存录像、录像回放、http-flv及hls协议分发
  • 了解AIGC——自然语言处理与生成
  • 数据结构 ——— 用队列实现栈
  • 构建自然灾害预警决策一体化平台,筑牢工程安全数字防线
  • 【C++】—— 模板进阶
  • sql server 之动态sql
  • 项目管理平台如何体现工程项目管理的主要特征?
  • 数据分析-38-关于互联网企业黑名单的探索
  • HarmonyOS NEXT应用元服务开发控件状态变化场景
  • Faster R-CNN
  • 2024第二届新能源汽车热管理论坛
  • 尚硅谷 | Nginx | 学习笔记
  • 开始实施!《商业银行业务档案管理规范》(DA/T 98-2023)
  • 【AI大模型】使用谷歌 Gemini API 构建自己的 ChatGPT(二)
  • Hugging Face | 个人使用笔记
  • Node-RED的面板的认识及操作
  • Linux第二讲:Linux权限理解
  • 海南华志亿星电子商务有限公司助力品牌销量飙升
  • 基于 ThinkPHP+Mysql 灵活用工_灵活用工系统_灵活用工平台
  • 通信原理概论复习笔记(2):模拟调制与数字调制
  • Spring Boot实用小技巧8 - 第530篇
  • 北京本盛数字科技有限公司-持续深耕AI智能化健康管理领域
  • nginx------HTTP模块配置详解
  • [论文笔记] 大模型评测:lm-evaluation-harnessPublic(eval-big-refactor)
  • 在 Gitee 或 GitCode 上克隆 Dify 项目源码并启动 Docker 环境
  • C++二级 求每个单词的长度的3种解决办法(包括find、substr)