鸿蒙 Web组件的生命周期(api10、11、12)

概述

开发者可以使用Web组件加载本地或者在线网页。

Web组件提供了丰富的组件生命周期回调接口,通过这些回调接口,开发者可以感知Web组件的生命周期状态变化,进行相关的业务处理。

Web组件的状态主要包括:Controller绑定到Web组件、网页加载开始、网页加载进度、网页加载结束、页面即将可见等。

在这里插入图片描述

Web组件网页加载的状态说明

(1)aboutToAppear函数:在创建自定义组件的新实例后,在执行其build函数前执行。一般建议在此设置WebDebug调试模式setWebDebuggingAccess、设置Web内核自定义协议URL的跨域请求与fetch请求的权限customizeSchemes、设置CookieconfigCookie等。

(2)onControllerAttached事件:当Controller成功绑定到Web组件时触发该回调,推荐在此事件中注入JS对象registerJavaScriptProxy、设置自定义用户代理setCustomUserAgent,可以在回调中使用loadUrl,getWebId等操作网页不相关的接口。但因该回调调用时网页还未加载,因此无法在回调中使用有关操作网页的接口,例如zoomIn、zoomOut等。

(3)onLoadIntercept事件:当Web组件加载url之前触发该回调,用于判断是否阻止此次访问。默认允许加载。

(4)onOverrideUrlLoading事件:当URL将要加载到当前Web中时,让宿主应用程序有机会获得控制权,回调函数返回true将导致当前Web中止加载URL,而返回false则会导致Web继续照常加载URL。onLoadIntercept接口和onOverrideUrlLoading接口行为不一致,触发时机也不同,所以在应用场景上存在一定区别。主要是在LoadUrl和iframe(HTML标签,表示HTML内联框架元素,用于将另一个页面嵌入到当前页面中)加载时,onLoadIntercept事件会正常回调到,但onOverrideUrlLoading事件则不会回调到。详细介绍请见onLoadIntercept和onOverrideUrlLoading的说明。

(5)onInterceptRequest事件:当Web组件加载url之前触发该回调,用于拦截url并返回响应数据。

(6)onPageBegin事件:网页开始加载时触发该回调,且只在主frame(表示一个HTML元素,用于展示HTML页面的HTML元素)触发。如果是iframe或者frameset(用于包含frame的HTML标签)的内容加载时则不会触发此回调。多frame页面有可能同时开始加载,即使主frame已经加载结束,子frame也有可能才开始或者继续加载中。同一页面导航(片段、历史状态等)或者在提交前失败、被取消的导航等也不会触发该回调。

(7)onProgressChange事件:告知开发者当前页面加载的进度。多frame页面或者子frame有可能还在继续加载而主frame可能已经加载结束,所以在onPageEnd事件后依然有可能收到该事件。

(8)onPageEnd事件:网页加载完成时触发该回调,且只在主frame触发。多frame页面有可能同时开始加载,即使主frame已经加载结束,子frame也有可能才开始或者继续加载中。同一页面导航(片段、历史状态等)或者在提交前失败、被取消的导航等也不会触发该回调。推荐在此回调中执行JavaScript脚本loadUrl等。需要注意的是收到该回调并不能保证Web绘制的下一帧将反映此时DOM的状态。

(9)onPageVisible事件:当HTTP响应的主体开始加载,新页面即将可见时触发该回调,且只在主frame触发。此回调在文档加载的早期触发,因此链接的资源比如在线CSS、在线图片等可能尚不可用。

(10)onRenderExited事件:应用渲染进程异常退出时触发该回调, 可以在此回调中进行系统资源的释放、数据的保存等操作。如果应用希望异常恢复,需要调用loadUrl接口重新加载页面。

(11)onDisAppear事件:组件卸载消失时触发此回调。该事件为通用事件,指组件从组件树上卸载时触发的事件。
应用侧代码:

// xxx.ets
import web_webview from '@ohos.web.webview';
import business_error from '@ohos.base';
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct WebComponent {
  controller: web_webview.WebviewController = new web_webview.WebviewController()
  responseWeb: WebResourceResponse = new WebResourceResponse()
  heads:Header[] = new Array()
  @State webData: string = "<!DOCTYPE html>\n" +
  "<html>\n" +
  "<head>\n" +
  "<title>intercept test</title>\n" +
  "</head>\n" +
  "<body>\n" +
  "<h1>intercept test</h1>\n" +
  "</body>\n" +
  "</html>"

aboutToAppear(): void {
  try {
    web_webview.WebviewController.setWebDebuggingAccess(true);
  } catch (error) {
    let e: business_error.BusinessError = error as business_error.BusinessError;
    console.error(`ErrorCode: ${e.code},  Message: ${e.message}`);
  }
}

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .onControllerAttached(() => {
          // 推荐在此loadUrl、设置自定义用户代理、注入JS对象等
          console.log('onControllerAttached excute')
        })
        .onLoadIntercept((event) => {
          if (event) {
            console.log('onLoadIntercept url:' + event.data.getRequestUrl())
            console.log('url:' + event.data.getRequestUrl())
            console.log('isMainFrame:' + event.data.isMainFrame())
            console.log('isRedirect:' + event.data.isRedirect())
            console.log('isRequestGesture:' + event.data.isRequestGesture())
          }
          // 返回true表示阻止此次加载,否则允许此次加载
          return true
        })
        .onOverrideUrlLoading((webResourceRequest: WebResourceRequest) => {
            if (webResourceRequest && webResourceRequest.getRequestUrl() == "about:blank") {
              return true;
            }
            return false;
        })
        .onInterceptRequest((event) => {
          if (event) {
            console.log('url:' + event.request.getRequestUrl())
          }
          let head1:Header = {
            headerKey:"Connection",
            headerValue:"keep-alive"
          }
          let head2:Header = {
            headerKey:"Cache-Control",
            headerValue:"no-cache"
          }
          let length = this.heads.push(head1)
          length = this.heads.push(head2)
          this.responseWeb.setResponseHeader(this.heads)
          this.responseWeb.setResponseData(this.webData)
          this.responseWeb.setResponseEncoding('utf-8')
          this.responseWeb.setResponseMimeType('text/html')
          this.responseWeb.setResponseCode(200)
          this.responseWeb.setReasonMessage('OK')
          // 返回响应数据则按照响应数据加载,无响应数据则返回null表示按照原来的方式加载
          return this.responseWeb
        })
        .onPageBegin((event) => {
          if (event) {
            console.log('onPageBegin url:' + event.url)
          }
        })
        .onFirstContentfulPaint(event => {
          if (event) {
            console.log("onFirstContentfulPaint:" + "[navigationStartTick]:" +
            event.navigationStartTick + ", [firstContentfulPaintMs]:" +
            event.firstContentfulPaintMs)
          }
        })
        .onProgressChange((event) => {
          if (event) {
            console.log('newProgress:' + event.newProgress)
          }
        })
        .onPageEnd((event) => {
          // 推荐在此事件中执行JavaScript脚本
          if (event) {
            console.log('onPageEnd url:' + event.url)
          }
        })
        .onPageVisible((event) => {
          console.log('onPageVisible url:' + event.url)
        })
        .onRenderExited((event) => {
          if (event) {
            console.log('onRenderExited reason:' + event.renderExitReason)
          }
        })
        .onDisAppear(() => {
          promptAction.showToast({
            message: 'The web is hidden',
            duration: 2000
          })
        })
    }
  }
}

前端index.html:

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
<h1>Hello, ArkWeb</h1>
</body>
</html>
<think>好的,用户问的是关于鸿蒙系统(HarmonyOS)的窗口开发API使用说明。首先,我需要确认用户提到的“鸿蒙window”具体指的是什么。鸿蒙系统本身有自己的一套窗口管理机制,可能涉及应用界面开发中的窗口组件API。 接下来,我需要回忆HarmonyOS的文档结构。HarmonyOS主要使用ArkUI框架,分为两种范式:类Web的声明式范式(JS/HTML/CSS)和声明式UI范式(ArkTS)。用户提到的窗口API可能属于ArkUI的一部分,或者是系统服务中的窗口管理器。 然后,考虑用户可能的开发场景。开发者可能在创建应用界面时,需要管理窗口的生命周期、设置窗口属性、处理窗口事件等。例如,全屏设置、窗口尺寸调整、模态窗口、分屏功能等。 需要分步骤介绍API的使用。首先,可能涉及如何获取窗口对象,比如通过窗口管理器获取当前窗口。然后,设置窗口属性,如大小、位置、背景色等。接着,处理窗口事件,比如显示、隐藏、焦点变化等。此外,高级功能如分屏、悬浮窗可能需要特定权限和API调用。 还要注意不同版本的HarmonyOS可能有不同的API支持,例如3.0或4.0版本之间的差异。需要提醒用户查阅对应版本的文档。 另外,用户可能对代码示例有需求,比如如何用ArkTS创建一个全屏窗口,或者监听窗口尺寸变化。需要确保示例代码符合HarmonyOS的最新语法,比如使用`@Entry`装饰器和`@Component`组件结构。 同时,要强调窗口开发中的常见问题,比如权限申请、兼容性处理、性能优化等。例如,悬浮窗需要用户授权,分屏功能需要检查系统是否支持。 最后,需要引导用户参考官方资源,如DevEco Studio的文档、HarmonyOS开发者官网的API参考,以及社区论坛中的案例。可能还需要提醒用户在实际开发中注意测试不同设备上的窗口表现,确保适配性。 总结回答的结构:先概述窗口API的作用,再分步骤介绍核心API的使用方法,提供示例代码,最后给出注意事项和参考资料。确保内容清晰,步骤明确,帮助用户逐步掌握鸿蒙窗口开发的相关API。</think>### 鸿蒙(HarmonyOS)窗口开发API使用说明 #### 一、HarmonyOS窗口开发概述 HarmonyOS的窗口管理基于**ArkUI框架**,通过系统级API实现窗口生命周期管理、属性设置、事件监听等功能。窗口API主要用于控制应用界面的显示方式(如全屏、分屏、悬浮窗等),需结合ArkTS/JS语言使用。 --- #### 二、核心API分类与使用步骤 ##### 1. **窗口对象获取** 通过`Window`模块获取当前窗口实例: ```typescript import window from '@ohos.window'; // 获取当前应用主窗口 let windowClass: window.Window; window.getLastWindow(getContext(this), (err, data) => { if (err) { console.error('获取窗口失败'); return; } windowClass = data; }); ``` ##### 2. **窗口属性设置** - **全屏模式**: ```typescript windowClass.setFullScreen(true, (err) => { if (err) console.error('全屏设置失败'); }); ``` - **窗口尺寸调整**: ```typescript windowClass.resize(800, 600, (err) => { if (err) console.error('尺寸调整失败'); }); ``` ##### 3. **窗口事件监听** - **窗口显示/隐藏**: ```typescript windowClass.on('windowShow', () => { console.log('窗口已显示'); }); windowClass.on('windowHide', () => { console.log('窗口已隐藏'); }); ``` - **焦点变化**: ```typescript windowClass.on('windowFocus', () => { console.log('窗口获得焦点'); }); ``` ##### 4. **高级功能** - **分屏模式**(需系统支持): ```typescript import display from '@ohos.display'; // 获取屏幕信息后设置分屏 display.getAllDisplays((err, displays) => { if (displays.length >= 2) { windowClass.setSplitScreen(true); } }); ``` - **悬浮窗**(需权限): ```typescript // 在config.json中申请权限 "reqPermissions": [ { "name": "ohos.permission.SYSTEM_FLOAT_WINDOW" } ] // 设置悬浮窗属性 windowClass.setWindowLayoutMode(window.WindowLayoutMode.FLOATING); ``` --- #### 三、注意事项 1. **权限控制**:部分API需在`config.json`中声明权限(如悬浮窗、分屏)。 2. **版本兼容性**:HarmonyOS 3.0+ 对窗口API支持更完善,需检查目标设备版本。 3. **生命周期管理**:窗口操作需在`onWindowStageCreate`生命周期内执行。 4. **性能优化**:避免频繁调整窗口属性,防止界面卡顿。 --- #### 四、官方参考资源 1. **API文档**:[HarmonyOS窗口开发指南](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-window-0000001581182898) 2. **开发工具**:使用DevEco Studio 3.0+ 进行调试。 3. **代码样例**:[HarmonyOS窗口示例工程](https://gitee.com/harmonyos/codelabs/tree/master/WindowManagement) --- 通过以上步骤,开发者可灵活控制鸿蒙应用的窗口行为。实际开发中建议结合场景测试不同设备的适配性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值