鸿蒙Web组件封装——零反射实现H5和Native协议通信

387 阅读5分钟

一、JumpUtils跳转PkWebView页面

介绍

实现原生与H5高效通信

导入依赖

import {JumpUtils}from '@peakmain/library'

1.1 跳转H5页面,携带token

public static jumpToH5(url: string, showTitle: boolean = true):void

参数

参数参数类型是否必填说明
urlstring跳转url
showTitleboolean是否显示导航栏,默认为true,表示显示

1.2 跳转到H5页面,携带token的同时携带version

public static jumpToH5AddVersion(url: string, showTitle: boolean = true):void

参数
参数参数类型是否必填说明
urlstring跳转url
showTitleboolean是否显示导航栏,默认为true,表示显示

1.3 跳转H5,拼接若干个参数

jumpToH5AddParams(url: string, showTitle: boolean = true, params: Map<string, string | number | boolean>,isAddToken: boolean = false):void

参数

参数参数类型是否必填说明
urlstring跳转url
showTitleboolean是否显示导航栏,默认为true,表示显示
paramsMap<string, string | number | boolean>需要拼接的参数
isAddTokenboolean是否拼接token,默认是false

1.4 为url添加版本号

static addVersionToUrl(url: string):string

参数

参数参数类型是否必填说明
urlstring跳转url

1.5 为url添加token

static addTokenToUrl(url: string):string

参数

参数参数类型是否必填说明
urlstring跳转url

二、WebViewComponent实现自定义Web页面

导入依赖

import {WebViewComponent} from '@peakmain/library';

参数

参数参数类型是否必填说明
urlstring跳转的url,默认是空字符串 ""
controllerwebview.WebviewControllerweb控制器,可以控制Web组件各种行为
titlestring标题,根据网页document标题展示对应标题
showTitleboolean显示标题是否显示标题
currentProgressNumbernumber当前进度
onErrorReceive(e: OnErrorReceiveEvent) => void错误回调,默认为空

示例代码

import { router } from '@kit.ArkUI'
import { webview } from '@kit.ArkWeb'
import { NavBar, WebViewComponent } from '../../components'
import { AVOID_AREA_HEIGHT, STATUS_BAR_HEIGHT } from '../../common'
import { WebViewBean } from '../../models'

@Entry({ routeName: "PkWebViewPage" })
@Component
struct PkWebViewPage {
  @StorageProp(STATUS_BAR_HEIGHT) statusBarHeight: number = 0
  @StorageProp(AVOID_AREA_HEIGHT) bottomSafeAreaHeight: number = 0;
  @State url: string = ""
  @State
  controller: webview.WebviewController = new webview.WebviewController()
  @State
  title: string = ""
  @State
  showTitle: boolean = true
  @State
  currentProgressNumber: number = 0
  onErrorReceive?: (e: OnErrorReceiveEvent) => void
  progressColor: ResourceColor = $r("app.color.color_A78461")

  aboutToAppear(): void {
    let bean = router.getParams() as WebViewBean
    this.url = bean.url
    this.showTitle = bean.showTitle
  }

  build() {
    Column() {
      if (this.showTitle) {
        NavBar({
          title: this.title,
          titleColor: Color.Black,
          leftClick: () => {
            if (this.controller.accessBackward()) {
              this.controller.backward()
            } else {
              router.back()
            }
          }
        })
      }
      if (this.currentProgressNumber < 100) {
        Progress({
          value: this.currentProgressNumber
        }).color(this.progressColor)
      }
      WebViewComponent({
        url: this.url,
        controller: this.controller,
        currentProgressNumber: this.currentProgressNumber,
        title: this.title,
        showTitle: this.showTitle,
        onErrorReceive: this.onErrorReceive
      })

    }
    .padding({ top: this.statusBarHeight })
    .margin({
      bottom: this.bottomSafeAreaHeight
    })
    .size({ width: '100%', height: '100%' })
  }
}
}

三、设置webView的userAgent

导入依赖

import {InitUtils} from '@peakmain/library';

方法

public setWebViewUserAgent(userAgent: string, isSuffix: boolean = true):InitUtils

参数

参数参数类型是否必填说明
userAgentstring自定义的userAgent
isSuffixboolean是否将自定义的userAgent添加到已有系统userAgent后面,默认是true

示例代码

 InitUtils.getInstance(this.context).setWebViewUserAgent(` AtourBrowser/${appVer}/Harmony`)

四、H5协议拦截和处理机制

介绍

在该系统中,我们支持拦截 H5 页面发出的协议请求,并通过定义相应的处理方法进行自定义处理。你可以根据需要定义协议的 scheme 和 authority,以及具体的路径(path),然后在代码中定义方法来处理这些请求

目标

我们需要拦截 H5 发出的协议(如 peakmain://page/login),并根据协议内容替换为自定义的处理方法。

协议结构

H5 协议通常包含如下格式:

scheme://authority/path
  • scheme:协议类型,例如 peakmain
  • authority:域名或 IP 地址
  • path:资源路径,例如 /page/login

导入依赖

import { Handle, HandleMethod, HandleResult, WebUrlBean } from '@peakmain/library';

1. 定义协议的 Scheme 和 Authority

在类上添加 @Handle 装饰器来定义协议的 scheme 和 authority。

@Handle参数说明

参数参数类型是否必填说明
schemestring协议类型
authoritystring域名或 IP 地址

示例

@Handle("peakmain", "page")
export class PageHandler {
  // 在这里定义方法
}

2. 定义协议的Path

在方法上添加 @HandleMethod 装饰器来指定该方法处理特定的路径

@HandleMethod 参数说明

参数参数类型是否必填说明
pathstring资源路径

示例代码

@Handle("peakmain", "page")
export class PageHandler {
  @HandleMethod("/login")
  login(bean:WebUrlBean): HandleResult {
    LogUtils.error("进入登录页面");
    return HandleResult.CONSUMED;  // 处理完后返回CONSUMED
  }
}

方法参数

WebUrlBean 是拦截协议后封装的参数,包含了协议的详细信息,传递给处理方法。

WebUrlBean 参数说明
参数类型说明
schemestring访问资源的协议或机制
authoritystring域名或IP地址
pathstring资源的具体位置或路径
controllerwebview.WebviewControllerWeb的控制器,可能为空
contextUIContext上下文,可能为空
paramsWebUrlParams&#124;nullH5给Native层的参数
WebUrlParams参数
参数类型说明
callIdstring执行的命令
dataobject参数数据

4.返回值:HandleResult

处理方法需要返回 HandleResult 枚举值,以指示协议是否已经被处理。

返回值类型说明
NOT_CONSUMEenum系统默认处理
CONSUMEDenum已处理,交给我们自己的处理方法
CONSUMINGenum正在处理中,暂不交给系统处理

示例代码

@Handle("peakmain", "page")
export class PageHandler {
  @HandleMethod("/login")
  login(): HandleResult {
    LogUtils.error("进入登录页面");
    return HandleResult.CONSUMED;  // 表示我们已经处理了该请求,不交给系统继续处理
  }
}

注意 实体类一定一定一定要初始化,初始化的方式有两种, ①、直接new 一个实体类,如下代码

new PageHandler()

②、通过InitUtils的initWebHandle方式初始化,如下代码

InitUtils.getInstance(this.context).init().initWebHandle(
      new PageHandler(),
      new UserHandler())
    )

五、Native发送协议给H5

JS方法定义

Native发送协议给H5通常格式是:

jsNameSpace.method.jsParams
  • jsNameSpace:JS 命名空间
  • method:JS 方法
  • jsParams:方法的参数

获取WebViewJsUtils

public static getInstance(jsNameSpace: string = "Prius"):WebViewJsUtils

参数

参数参数类型是否必填说明
jsNameSpacestring执行的 JS 命名空间前缀,默认为 Prius
说明

该方法用于获取 WebViewJsUtils 的实例,可以指定 JS 命名空间,也可以使用默认的 Prius

1. 执行js的onCallbackDone方法

executeDoneJs(control: webview.WebviewController | null, data: string): boolean

参数

参数参数类型是否必填说明
controllerwebview.WebviewControllerWeb的控制器,可为空
datastring数据源,不需要加密
说明

此方法用于在 JS 中执行回调成功的操作。返回值为 boolean,表示是否成功执行。

2. 执行js的onCallbackFail方法

executeFailureJs(control: webview.WebviewController | null, data: string): boolean

参数

参数参数类型是否必填说明
controllerwebview.WebviewControllerWeb的控制器,可为空
datastring数据源,不需要加密
说明

此方法用于在 JS 中执行回调成功的操作。返回值为 boolean,表示是否成功执行。

3. 执行指定js的方法

executeJs(control: webview.WebviewController | null, method: string, ...datas: string[])

参数

参数参数类型是否必填说明
controllerwebview.WebviewControllerWeb的控制器,可为空
methodstring执行的方法
datastring[]数据源,不需要加密
说明

此方法用于在 WebView 中执行指定的 JS 方法,并传递参数。返回类型为 void,无返回值。