feat(基础组件): 新增 XWebview 消息交互功能- 新增 XWebController 接口和 XWebManager 类

- 实现了 XWebview 和原生代码之间的消息通信机制
- 更新了 MiniAppManager 中的 XWebHelper 使用新的消息通信功能- 优化了 XWebview组件,支持消息端口通信
这个提交包含在:
徐勤民 2024-11-22 17:35:12 +08:00
父节点 268d9f4fb2
当前提交 fbca6847f1
共有 3 个文件被更改,包括 129 次插入27 次删除

查看文件

@ -1,14 +1,16 @@
import web_webview from '@ohos.web.webview'; import web_webview from '@ohos.web.webview';
import webview from '@ohos.web.webview';
import { router } from '@kit.ArkUI'; import { router } from '@kit.ArkUI';
import { XDialogController } from '../dialog/XDialogController'; import { XDialogController } from '../dialog/XDialogController';
import { XDialogList } from '../dialog/XDialogList'; import { XDialogList } from '../dialog/XDialogList';
import { picker } from '@kit.CoreFileKit'; import { picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit';
import { ToolsHelper } from '../utils/ToolsHelper'; import { ToolsHelper } from '../utils/ToolsHelper';
import { XWebParams } from '../utils/XWebHelper'; import { XWebController, XWebParams } from '../utils/XWebHelper';
import { WindowHelper } from '../utils/WindowHelper'; import { WindowHelper } from '../utils/WindowHelper';
import { SZYXLocalStorageHelper } from '../utils/SZYXLocalStorageHelper'; import { SZYXLocalStorageHelper } from '../utils/SZYXLocalStorageHelper';
import { SZYXLocalStorageKeys } from '../utils/SZYXLocalStorageKeys'; import { SZYXLocalStorageKeys } from '../utils/SZYXLocalStorageKeys';
import { XWebManager } from '../utils/XWebManager';
@Entry({ routeName: 'XWebview' }) @Entry({ routeName: 'XWebview' })
@Component @Component
@ -18,20 +20,26 @@ export struct XWebview {
@State zoomAccess?: boolean = (router.getParams() as XWebParams).zoomAccess @State zoomAccess?: boolean = (router.getParams() as XWebParams).zoomAccess
@State content?: string = (router.getParams() as XWebParams).content @State content?: string = (router.getParams() as XWebParams).content
@State title?: string = (router.getParams() as XWebParams).title @State title?: string = (router.getParams() as XWebParams).title
@State xController?: XWebController = (router.getParams() as XWebParams).controller
@State closeTag?: string = (router.getParams() as XWebParams).closeTag @State closeTag?: string = (router.getParams() as XWebParams).closeTag
@State showMenu: boolean = (router.getParams() as XWebParams).showMenu ?? false @State showMenu: boolean = (router.getParams() as XWebParams).showMenu ?? false
@State errorInfo: string | null = null @State errorInfo: string | null = null
@State progress: number = 0 @State progress: number = 0
@State _uuid?: string = (router.getParams() as XWebParams)._uuid
@State _uuidToHtml?: string = (router.getParams() as XWebParams)._uuidToHtml
controller: web_webview.WebviewController = new web_webview.WebviewController(); controller: web_webview.WebviewController = new web_webview.WebviewController();
dialogController: XDialogController = {} as XDialogController dialogController: XDialogController = {} as XDialogController
ports: webview.WebMessagePort[] = [];
aboutToAppear(): void { aboutToAppear(): void {
SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.XWebViewCLose, undefined) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.XWebViewCLose, undefined)
webview.WebviewController.setWebDebuggingAccess(true);
if (this.content) { if (this.content) {
try { try {
this.controller.loadData(this.content, this.controller.loadData(this.content,
"text/html", "text/html",
"UTF-8") "UTF-8", '', '')
} catch (e) { } catch (e) {
ToolsHelper.showAlertDialog({ ToolsHelper.showAlertDialog({
title: '警告', title: '警告',
@ -44,12 +52,21 @@ export struct XWebview {
}) })
} }
} }
if (this._uuidToHtml) {
XWebManager.addOnMessageToHtml(this._uuidToHtml, (msg) => {
if (this.ports && this.ports[1]) {
this.ports[1].postMessageEvent(msg);
}
})
}
} }
aboutToDisappear(): void { aboutToDisappear(): void {
if (this.closeTag !== undefined) { if (this.closeTag !== undefined) {
SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.XWebViewCLose, this.closeTag) SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.XWebViewCLose, this.closeTag)
} }
XWebManager.removeOnMessage(this._uuid)
XWebManager.removeOnMessageToHtml(this._uuidToHtml)
} }
onBackPress(): boolean | void { onBackPress(): boolean | void {
@ -123,9 +140,9 @@ export struct XWebview {
.height('100%') .height('100%')
.visibility(this.errorInfo == null ? Visibility.Visible : Visibility.None) .visibility(this.errorInfo == null ? Visibility.Visible : Visibility.None)
.mixedMode(MixedMode.All)//允许加载HTTP和HTTPS混合内容 .mixedMode(MixedMode.All)//允许加载HTTP和HTTPS混合内容
.zoomAccess(this.zoomAccess??false)//不支持手势进行缩放 .zoomAccess(this.zoomAccess ?? false)//不支持手势进行缩放
.mediaPlayGestureAccess(false)//有声视频播放不需要用户手动点击 .mediaPlayGestureAccess(false)//有声视频播放不需要用户手动点击
.cacheMode(CacheMode.Default)//设置缓存模式 .cacheMode(CacheMode.None)//设置缓存模式
.onConfirm((event) => { // 自定义Confirm弹窗 .onConfirm((event) => { // 自定义Confirm弹窗
if (event) { if (event) {
console.log("event.url:" + event.url) console.log("event.url:" + event.url)
@ -178,28 +195,50 @@ export struct XWebview {
console.log('mimetype:' + event.mimetype) console.log('mimetype:' + event.mimetype)
} }
}) })
// .onErrorReceive((event) => { // 加载失败 .onPageEnd((url) => {
// if (this.progress > 65) { ToolsHelper.log(url.url)
// return // 1、创建两个消息端口。
// } this.ports = this.controller.createWebMessagePorts();
// if (event) { this.ports[1].onMessageEvent((result: webview.WebMessage) => {
// this.errorInfo = `错误码:${event.error.getErrorCode()}\n${event.error.getErrorInfo()}` if (typeof (result) === 'string') {
// } else { ToolsHelper.log(result, typeof (result))
// this.errorInfo = '错误码:-1\n未知错误' XWebManager.sendMessage(result)
// } }
// ToolsHelper.log(JSON.stringify(event),this.url) })
// }) this.controller.postMessage('__init_port__', [this.ports[0]], '*');
// .onHttpErrorReceive((event) => { // 加载失败 })
// if (this.progress > 65) { .onControllerAttached(() => {
// return try {
// } let userAgent = this.controller.getUserAgent() + '/szyx_sdk';
// if (event) { this.controller.setCustomUserAgent(userAgent);
// this.errorInfo = `错误码:${event.response.getResponseCode()}\n${event.response.getReasonMessage()}` // this.controller.runJavaScript('window.SZYX_YWX_WebViewBridge.onIsYwxApp()');
// } else {
// this.errorInfo = '错误码:-1\n未知错误' } catch (error) {
// } console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
// ToolsHelper.log( this.errorInfo,this.url) }
// }) })
.onErrorReceive((event) => { // 加载失败
if (this.progress > 65) {
return
}
if (event) {
this.errorInfo = `错误码:${event.error.getErrorCode()}\n${event.error.getErrorInfo()}`
} else {
this.errorInfo = '错误码:-1\n未知错误'
}
ToolsHelper.log(JSON.stringify(event), this.url)
})
.onHttpErrorReceive((event) => { // 加载失败
if (this.progress > 65) {
return
}
if (event) {
this.errorInfo = `错误码:${event.response.getResponseCode()}\n${event.response.getReasonMessage()}`
} else {
this.errorInfo = '错误码:-1\n未知错误'
}
ToolsHelper.log(this.errorInfo, this.url)
})
.onProgressChange((event) => { // 加载进度 .onProgressChange((event) => { // 加载进度
if (event) { if (event) {
console.log('newProgress:' + event.newProgress) console.log('newProgress:' + event.newProgress)

查看文件

@ -3,10 +3,15 @@ import { BusinessError } from '@kit.BasicServicesKit';
import { LogHelper } from '../../../../Index'; import { LogHelper } from '../../../../Index';
import { baseEncode } from '../util/base64Util'; import { baseEncode } from '../util/base64Util';
import { ToolsHelper } from './ToolsHelper'; import { ToolsHelper } from './ToolsHelper';
import { XWebManager } from './XWebManager';
const XWebview = import('../pages/XWebview'); const XWebview = import('../pages/XWebview');
export interface XWebController {
sendMessage: (message: string) => void
}
export interface XWebParams { export interface XWebParams {
url?: string url?: string
zoomAccess?: boolean zoomAccess?: boolean
@ -15,6 +20,10 @@ export interface XWebParams {
showMenu?: boolean showMenu?: boolean
closeTag?: string closeTag?: string
watermarkTxt?: string watermarkTxt?: string
_uuid?: string
_uuidToHtml?: string
onMessage?: (message: string) => void
controller?: XWebController
} }
export class XWebHelper { export class XWebHelper {
@ -26,6 +35,16 @@ export class XWebHelper {
* @param params * @param params
*/ */
public static openWeb(params: XWebParams): Promise<boolean> { public static openWeb(params: XWebParams): Promise<boolean> {
if (params.onMessage) {
params._uuid = XWebManager.addOnMessage(params.onMessage)
}
if (params.controller) {
params._uuidToHtml = ToolsHelper.getUuid()
params.controller.sendMessage = (msg) => {
XWebManager.sendMessageToHtml(msg)
}
}
return new Promise((resolve) => { return new Promise((resolve) => {
router.pushNamedRoute({ router.pushNamedRoute({
name: 'XWebview', name: 'XWebview',
@ -40,8 +59,11 @@ export class XWebHelper {
}) })
}) })
} }
public static openPreview(params: XWebParams): Promise<boolean> { public static openPreview(params: XWebParams): Promise<boolean> {
params.url = `https://mdtdemo.51trust.com/preview/onlinePreview?url=${baseEncode(params.url)}&watermarkTxt=${encodeURI(params.watermarkTxt??'')}` params.url =
`https://mdtdemo.51trust.com/preview/onlinePreview?url=${baseEncode(params.url)}&watermarkTxt=${encodeURI(params.watermarkTxt ??
'')}`
return new Promise((resolve) => { return new Promise((resolve) => {
router.pushNamedRoute({ router.pushNamedRoute({
name: 'XWebview', name: 'XWebview',

查看文件

@ -0,0 +1,41 @@
import { ToolsHelper } from './ToolsHelper';
export class XWebManager {
private static MapEventListener = new Map<string, (msg: string) => void>();
static addOnMessage(listener: (msg: string) => void): string {
const id = ToolsHelper.getUuid()
XWebManager.MapEventListener.set(id, listener)
return id
}
static removeOnMessage(id?: string) {
if (id) {
XWebManager.MapEventListener.delete(id)
}
}
static sendMessage(message: string) {
for (let item of XWebManager.MapEventListener.values()) {
item(message)
}
}
private static MapEventListenerToHtml = new Map<string, (msg: string) => void>();
static addOnMessageToHtml(id: string, listener: (msg: string) => void) {
XWebManager.MapEventListenerToHtml.set(id, listener)
}
static removeOnMessageToHtml(id?: string) {
if (id) {
XWebManager.MapEventListenerToHtml.delete(id)
}
}
static sendMessageToHtml(message: string) {
for (let item of XWebManager.MapEventListenerToHtml.values()) {
item(message)
}
}
}