ArkWeb 介绍

Web 组件用于在应用程序中显示 Web 页面内容,为开发者提供页面加载、页面交互、页面调试等能力。可以用于实现移动端的混合式开发(Hybrid App):

  • 页面加载:Web 组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、html 格式文本数据。
  • 页面交互:Web 组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,Cookie 管理,应用侧使用前端页面JavaScript 等能力。
  • 页面调试:Web 组件支持使用 Devtools 工具调试前端页面。

ArkWeb API

  • Web 组件:提供具有网页显示能力的一种组件。
  • Webview:提供 web 控制能力的相关接口。

Web 组件的生命周期

  • onControllerAttached 事件:当 Controller 成功绑定到 Web 组件时触发该回调。
  • onLoadIntercept 事件:当 Web 组件加载 url 之前触发该回调,用于判断是否阻止此次访问。默认允许加载。
  • onInterceptRequest 事件:当 Web 组件加载 url 之前触发该回调,用于拦截 url 并返回响应数据。
  • onPageBegin 事件:网页开始加载时触发该回调。
  • onProgressChange 事件:告知开发者当前页面加载的进度。
  • onPageEnd 事件:网页加载完成时触发该回调。
  • onPageVisible 事件:当 HTTP 响应的主体开始加载,新页面即将可见时触发该回调,且只在主 frame 触发。
  • onRenderExited 事件:应用渲染进程异常退出时触发该回调, 可以在此回调中进行系统资源的释放、数据的保存等操作。

ArkWeb 高频场景1:页面加载、显示及导航

  • 加载网络页面:开发者可以在 Web 组件创建时,指定默认加载的网络页面 。在默认页面加载完成后,如果开发者需要变更此 Web 组件显示的网络页面,可以通过调用 loadUrl() 接口加载指定的网页。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
webviewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadUrl').onClick(() => {
try {
// 点击按钮时,通过loadUrl,跳转到www.example1.com
this.webviewController.loadUrl('www.example1.com');
} catch (error) {
...
}
})
// 组件创建时,加载www.example.com
Web({ src: 'www.example.com', controller: this.webviewController})
}
}
}
  • 加载本地页面:将本地页面文件放在应用的 rawfile 目录下,开发者可以在 Web 组件创建的时候指定默认加载的本地页面 ,并且加载完成后可通过调用 loadUrl() 接口变更当前 Web 组件的页面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
webviewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadUrl').onClick(() => {
try {
// 点击按钮时,通过loadUrl,跳转到local1.html
this.webviewController.loadUrl($rawfile("local1.html"));
} catch (error) {
...
}
})
// 组件创建时,通过$rawfile加载本地文件local.html
Web({ src: $rawfile("local.html"), controller: this.webviewController })
}
}
}
  • 加载 HTML 格式数据:Web 组件可以通过 loadData() 接口实现加载HTML 格式的文本数据。当开发者不需要加载整个页面,只需要显示一
    些页面片段时,可通过此功能来快速加载页面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadData').onClick(() => {
try {
// 点击按钮时,通过loadData,加载HTML格式的文本数据
this.controller.loadData(
"<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>",
"text/html",
"UTF-8"
);
} catch (error) {

}
})
// 组件创建时,加载www.example.com
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
  • 历史记录导航:在前端页面点击网页中的链接时,Web组件默认会自动打开并加载目标网址。当前端页面替换为新的加载链接时,会自动记录已经访问的网页地址。可以通过 forward()backward() 接口向前/向后浏览上一个/下一个历史记录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
webviewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('Backward').onClick(() => {
if (this.webviewController.accessBackward()) {
this.webviewController.backward();
}
})
Web({ src: 'https://www.example.com/cn/', controller: this.webviewController})
}
}
}
  • 页面跳转:当点击网页中的链接需要跳转到应用内其他页面时,可以通过使用 Web 组件的 onLoadIntercept() 接口来实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct WebComponent {
webviewController: webview.WebviewController
= new webview.WebviewController();
build() {
Column() {
Web({ src: $rawfile('route.html'), controller: this.webviewController }).onLoadIntercept((event) => {
if (event) {
let url: string = event.data.toString();
if (url.indexOf('native://') === 0) {
// 跳转其他界面
router.pushUrl({ url:url.substring(9) })
return true;
}
}
return false;
})
}
}
}
  • 跨应用跳转:Web 组件可以实现点击前端页面超链接跳转到其他应用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Entry
@Component
struct WebComponent {
webviewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: $rawfile('call.html'), controller: this.webviewController}).onLoadIntercept((event) => {
if (event) {
let url: string = event.data.toString();
// 判断链接是否为拨号链接
if (url.indexOf('tel://') === 0) {
// 跳转拨号界面
call.makeCall(url.substring(6), (err) => { ... });
return true;
}
}
return false;
})
}
}
}

<!--前端页面 call.html 代码-->
<!-- call.html -->
<!DOCTYPE html>
<html>
<body>
<div>
<a href="tel://xxx xxxx xxx">拨打电话</a>
</div>
</body>
</html>