在鸿蒙应用开发中,高效管理网页加载与浏览记录是提升用户体验的关键,ArkWeb提供了完整的解决方案。
HarmonyOS Next 的 ArkWeb 组件是一个强大的 Web 视图框架,允许开发者在鸿蒙应用中嵌入 Web 内容,并提供了丰富的 API 来管理网页加载、导航和用户交互。
本文将深入探讨如何使用 ArkWeb 管理网页加载与浏览记录,帮助您打造更流畅的 Web 浏览体验。
一、ArkWeb 简介与基础用法
ArkWeb 是华为鸿蒙系统提供的 Web 应用框架,允许开发者将 Web 页面嵌入到鸿蒙应用中并与之交互。它支持多种使用场景:
-
应用集成 Web 页面:降低开发成本,提升开发效率
-
浏览器网页浏览:打开三方网页,使用无痕模式浏览
-
小程序渲染:作为小程序类宿主应用渲染小程序页面
基本使用方式如下:
javascript
import { webview } from '@kit.ArkWeb'; @Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); build() { Column() { Web({ src: "https://www.example.com", controller: this.controller }) } } }
二、页面加载管理
ArkWeb 提供了多种页面加载方式,满足不同场景需求。
1. 加载网络页面
有两种方式加载网络页面:
使用 src 属性直接加载:
javascript
Web({ src: "https://www.example.com" })
使用 loadUrl 方法动态加载:
javascript
Web({ src: $rawfile("local.html") }) .onControllerAttached(() => { this.controller.loadUrl("https://www.example.com"); })
2. 加载本地页面
同样有两种方式加载本地页面:
使用 $rawfile 加载:
javascript
Web({ src: $rawfile("local.html") })
使用 loadUrl 加载本地页面:
javascript
Web({ src: $rawfile("local.html") }) .onControllerAttached(() => { this.controller.loadUrl($rawfile("another_local.html")); })
3. 加载 HTML 文本数据
可以使用 loadData 方法直接加载 HTML 文本内容:
javascript
Web({ src: $rawfile("local.html") }) .onControllerAttached(() => { this.controller.loadData("<html><body>Hello, World!</body></html>", "text/html", "UTF-8"); })
需要指定数据类型、编码格式和内容。
4. 加载模式选择
ArkWeb 支持两种加载模式:
-
同步渲染模式(默认):Web 渲染与系统组件一起进行
-
异步渲染模式:Web 组件作为独立节点渲染,性能更高,但受限于最大尺寸
可以通过 renderMode 属性设置加载模式:
javascript
Web({ src: "https://www.example.com", renderMode: RenderMode.ASYNC_RENDER })
5. 加载进度监听
可以使用 onProgressChange 接口监听页面加载进度:
javascript
Web({ src: "https://www.example.com" }) .onProgressChange((event) => { console.log("Loading progress: " + event.newProgress); })
三、浏览记录导航管理
在前端页面点击网页中的链接时,Web 组件默认会自动打开并加载目标网址,并自动记录已访问的网页地址。
1. 前进和后退操作
可以使用 forward 和 backward 方法进行页面前进和后退操作:
javascript
Web({ src: "https://www.example.com" }) .onControllerAttached(() => { this.controller.forward(); // 前进 this.controller.backward(); // 后退 })
2. 检查历史记录
在执行前进后退操作前,最好先检查是否存在相应的历史记录:
javascript
Web({ src: "https://www.example.com" }) .onControllerAttached(() => { if (this.controller.accessForward()) { this.controller.forward(); // 存在前进历史记录,可以前进 } if (this.controller.accessBackward()) { this.controller.backward(); // 存在后退历史记录,可以后退 } })
如果存在历史记录,accessBackward()
接口会返回 true
。同样,可以使用 accessForward()
接口检查是否存在前进的历史记录。如果不执行检查,当用户浏览到历史记录的末尾时,调用 forward()
和 backward()
接口将不执行任何操作。
3. 完整示例
下面是一个完整的浏览记录导航示例:
javascript
// xxx.ets import { webview } from '@kit.ArkWeb'; @Entry @Component struct WebComponent { webviewController: webview.WebviewController = new webview.WebviewController(); build() { Column() { Button('后退') .onClick(() => { if (this.webviewController.accessBackward()) { this.webviewController.backward(); } }) Button('前进') .onClick(() => { if (this.webviewController.accessForward()) { this.webviewController.forward(); } }) Web({ src: 'https://www.example.com/cn/', controller: this.webviewController }) } } }
四、页面跳转管理
ArkWeb 还提供了强大的页面跳转管理能力,可以实现应用内页面跳转和跨应用跳转。
1. 应用内页面跳转
当点击网页中的链接需要跳转到应用内其他页面时,可以通过使用 Web 组件的 onUrlLoadIntercept() 接口来实现。
以下示例展示了如何从 Web 页面跳转到应用内其他页面:
应用首页 index.ets 代码:
javascript
// index.ets import { webview } from '@kit.ArkWeb'; import { router } from '@kit.ArkUI'; @Entry @Component struct WebComponent { webviewController: webview.WebviewController = new webview.WebviewController(); build() { Column() { Web({ src: $rawfile('route.html'), controller: this.webviewController }) .onUrlLoadIntercept((event) => { if (event) { let url: string = event.data.getRequestUrl(); if (url.indexOf('native://') === 0) { // 跳转其他界面 router.pushUrl({ url: url.substring(9) }); return true; } } return false; }) } } }
前端页面 route.html 代码:
html
<!-- route.html --> <!DOCTYPE html> <html> <body> <div> <a href="native://pages/ProfilePage">个人中心</a> </div> </body> </html>
跳转页面 ProfilePage.ets 代码:
javascript
@Entry @Component struct ProfilePage { @State message: string = 'Hello World'; build() { Column() { Text(this.message) .fontSize(20) } } }
2. 跨应用跳转
Web 组件可以实现点击前端页面超链接跳转到其他应用。
以下示例展示了如何从 Web 页面跳转到电话应用的拨号界面:
应用侧代码:
javascript
// xxx.ets import { webview } from '@kit.ArkWeb'; import { call } from '@kit.TelephonyKit'; @Entry @Component struct WebComponent { webviewController: webview.WebviewController = new webview.WebviewController(); build() { Column() { Web({ src: $rawfile('call.html'), controller: this.webviewController }) .onUrlLoadIntercept((event) => { if (event) { let url: string = event.data.getRequestUrl(); // 判断链接是否为拨号链接 if (url.indexOf('tel://') === 0) { // 跳转拨号界面 call.makeCall(url.substring(6), (err) => { if (!err) { console.info('make call succeeded.'); } else { console.info('make call fail, err is:' + JSON.stringify(err)); } }); return true; } } return false; }) } } }
前端页面 call.html 代码:
html
<!-- call.html --> <!DOCTYPE html> <html> <body> <div> <a href="tel://xxx xxxx xxx">拨打电话</a> </div> </body> </html>
五、生命周期与性能监控
ArkWeb 提供了丰富的生命周期回调接口,开发者可以通过这些接口感知 Web 组件的生命周期状态变化,并进行相关的业务处理。
1. 主要生命周期回调
-
onControllerAttached:当 Controller 成功绑定到 Web 组件时触发
-
onPageBegin:网页开始加载时触发
-
onProgressChange:告知开发者当前页面加载的进度
-
onPageEnd:网页加载完成时触发
-
onPageVisible:页面即将可见时触发
-
onRenderExited:应用渲染进程异常退出时触发
-
onDisAppear:组件卸载消失时触发
2. 性能监控
ArkWeb 提供了性能监控接口,可以获取网页加载过程中的关键性能指标:
-
onFirstContentfulPaint:网页首次内容绘制的回调函数
-
onFirstMeaningfulPaint:网页首次有效绘制的回调函数
-
onLargestContentfulPaint:网页绘制页面最大内容的回调函数
使用示例:
javascript
@Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); build() { Column() { Web({ src: "https://www.example.com", controller: this.controller }) .onFirstContentfulPaint(event => { if (event) { console.log("onFirstContentfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstContentfulPaintMs]:" + event.firstContentfulPaintMs); } }) .onFirstMeaningfulPaint(event => { if (event) { console.log("onFirstMeaningfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstMeaningfulPaintMs]:" + event.firstMeaningfulPaintMs); } }) .onLargestContentfulPaint(event => { if (event) { console.log("LargestContentfulPaint:" + event.largestContentfulPaintMs); } }) } } }
3. 统计网页访问时长
可以通过生命周期回调统计每个网页的访问时长:
javascript
@Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); startTime: number = 0; currentUrl: string = ''; build() { Column() { Web({ src: "https://www.example.com", controller: this.controller }) .onPageBegin((event) => { if (event) { this.startTime = new Date().getTime(); this.currentUrl = event.url; console.log('页面开始加载: ' + event.url); } }) .onPageEnd((event) => { if (event) { const endTime = new Date().getTime(); const duration = endTime - this.startTime; console.log(`页面 ${this.currentUrl} 加载完成,耗时 ${duration} 毫秒`); // 上报访问时长数据 this.reportPageDuration(this.currentUrl, duration); } }) } } // 上报页面访问时长 reportPageDuration(url: string, duration: number) { // 实现数据上报逻辑 } }
六、最佳实践与注意事项
-
权限配置:页面加载过程中,若涉及网络资源获取,需要配置
ohos.permission.INTERNET
网络访问权限。 -
内存管理:对于大量使用 Web 组件的应用,需要注意内存管理,及时释放不再使用的 Web 组件。
-
性能优化:对于性能要求较高的场景,可以考虑使用异步渲染模式:
RenderMode.ASYNC_RENDER
。 -
错误处理:合理处理网页加载失败、网络异常等情况,提供友好的用户提示。
-
安全考虑:对拦截的 URL 进行严格验证,防止安全漏洞。
总结
ArkWeb 提供了强大而灵活的网页加载与浏览记录管理功能,使开发者能够轻松地在鸿蒙应用中集成 Web 内容,并提供原生般的用户体验。
通过合理利用页面加载方式、浏览记录导航、生命周期回调和性能监控接口,可以打造出高性能、用户体验良好的 Web 浏览功能。
掌握了 ArkWeb 的这些特性,相信你能够更加高效地开发鸿蒙应用,轻松应对各种 Web 内容集成场景。