鸿蒙 ArkWeb 和 H5混编开发

发布于:2025-06-19 ⋅ 阅读:(30) ⋅ 点赞:(0)

ArkWeb

Web 相关标准技术(HTML/CSS/JS),是业内支持性最广泛的技术,可以在最广泛的平台下实现“一次编写到处运行”;大部分对性能无需极致要求的应用页面,都可以使用 Web 技术来实现。

鸿蒙 ArkWeb Kit(方舟 Web)提供了 Web 组件(也称为 Webview 组件),本质就是 HTML/CSS/JS 解释和渲染引擎,用于在应用程序中显示 Web 页面内容,为开发者提供页面加载、页面交互、页面调试等能力。

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

当前鸿蒙系统中的 Web 组件底层实现是开源的 Chromium 内核(Webkit + V8 组合);华为未来计划完全自主实现该组件。

Web 组件生命周期

  • aboutToAppear:可设置调试模式 / 跨域请求权限 / Cookie 等
  • onControllerAttached:推荐在此 loadUrl / 设置自定义用户代理 / 注入 JS 对象等
  • onLoadIntercept:当 Web 组件加载 url 之前触发该回调,用于判断是否阻止此次访问。默认 false 表允许加载
  • onInterceptRequest:当 Web 组件加载 url 之前触发该回调,用于拦截 url 并返回响应数据
  • onPageBegin:网页开始加载时触发该回调
  • onProgressChange:网页开始加载时触发该回调
  • onPageEnd:网页加载完成时触发该回调,推荐在此回调中执行 runJavaScript()异步执行 JS
  • onPageVisible:当响应的主体开始加载,新页面即将可见时触发该回调;此时外链资源尚不可用
  • onDisAppear:组件卸载消失时触发此回调

加载网络页面

开发者可以在 Web 组件创建时,指定默认加载的网络页面 。在默认页面加载完成后,如果开发者需要变更此 Web 组件显示的网络页面,可以通过调用 loadUrl()接口加载指定的网页。

import { webview } from '@kit.ArkWeb'

struct Page{
  controller = new webview.WebviewController( )

  build() {
    Column() {
      Button('loadUrl')
        .onClick(() => {
  this.controller.loadUrl('www.10086.cn')       //按钮点击后,加载第二个页面
        })
      // 组件创建时,加载第一个页面
      Web({ src: 'www.baidu.com', controller: this.controller})
    }
  }
}

涉及网络资源获取,需要配置 ohos.permission.INTERNET 权限

加载本地页面

将本地页面文件放在应用的 rawfile 目录下,开发者可以在 Web 组件创建的时候指定默认加载的本地页面 ,并且加载完成后可通过调用 loadUrl() 接口变更当前 Web 组件的页面。

import { webview } from '@kit.ArkWeb'

struct Page{
  controller = new webview.WebviewController( )
  build() {
    Column() {
      Button('loadPage')
        .onClick(() => {
  this.controller.loadUrl( $rawfile("notfound.html") )     //加载第二个页面
        })
      // 组件创建时,加载第一个页面
      Web({ src:  $rawfile("loading.html"), controller: this.controller})
    }
  }
}

加载 HTML 数据

Web 组件可以通过 loadData() 接口实现加载 HTML 格式的文本数据。当开发者不需要加载整个页面,只需要显示一些页面片段时,可通过此功能来快速加载页面。

import { webview } from '@kit.ArkWeb'
struct Page{
  controller = new webview.WebviewController()
  build() {
    Column() {
      Button('loadData')
        .onClick(() => {
  this.controller.loadData(       //按钮点击后,加载HTML片段
              "<html><body>Source:<pre>source</pre></body></html>",
              "text/html",
              "UTF-8"  )
        })
      // 组件创建时,加载第一个页面
      Web({ src:  $rawfile("loading.html"), controller: this.controller })
    }
  }
}

应用侧和 Web 侧交互

数据通道

Web 侧和应用侧之间可以用 createWebMessagePorts() 创建两个消息端口来实现两端的通信

//应用侧(ArkTS) —— 使用端口1发消息
ports: webview.WebMessagePort[ ] = [ ]

this.ports = this.controller.createWebMessagePorts( )   //会创建两个Port对象
this.controller.postMessage('init', [this.ports[0]], '*')

this.ports[1].onMessageEvent((msg: webview.WebMessage) => {})
this.ports[1].postMessageEvent('msg')
//Web侧(JS) —— 使用端口0发消息
let port = null;
window.addEventListener("message", (e) => {
  port = e.ports[0];
  port.onmessage = (m) => {};
});
bt.onclick = () => {
  port.postMessage("This is Client - " + Date.now());
};

应用侧调 Web 侧函数

应用侧可以通过 runJavaScript( ) 方法调用前端页面的 JavaScript 相关函数:

前端页面声明 JS 函数:

<script>
  function startLottery() {
    //开始
  }
</script>

应用侧调用前端页面函数:

Button("运行JS代码").onClick(() => {
  this.controller.runJavaScript("startLottery( )");
  //需要传参的话也可以在上述函数调用过程中传递,返回值可以在Promise中读取
});

Web 侧调应用侧函数

开发者使用 Web 组件将应用侧代码 注册 到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。
应用侧注册对象和方法(代理方法)给前端页面:

Web({
  src: $rawfile("page.html"),
  controller: this.controller,
}).javaScriptProxy({
  //给Web侧注册一个代理对象
  object: this, //被代理的对象
  name: "appObj", //代理人在Web端的名称
  methodList: ["back"], //被代理的对象中哪些方法要暴露给Web侧
  controller: this.controller,
});

前端页面调用应用侧注册来的对象和方法:

<script>
  btn.onclick = () => {
    appObj.back(); //需要传参的话可以在形参处传递,返回值可以在Promise中读取
  };
</script>

网站公告

今日签到

点亮在社区的每一天
去签到