当前位置:首页 » 《关注互联网》 » 正文

HarmonyOS Next开发学习手册——ArkWeb

29 人参与  2024年09月30日 10:40  分类 : 《关注互联网》  评论

点击全文阅读


ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。

页面加载:Web组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、html格式文本数据。

页面交互:Web组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,Cookie管理,应用侧使用前端页面JavaScript等能力。

页面调试:Web组件支持使用 Devtools工具 调试前端页面。

下面通过常见使用场景举例,来具体介绍Web组件功能特性。

Web组件的生命周期

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

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

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

图1 Web组件网页正常加载过程中的回调事件

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

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

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

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

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

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

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

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

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

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

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

onDisAppear 事件:组件卸载消失时触发此回调。该事件为通用事件,指组件从组件树上卸载时触发的事件。

应用侧代码。

// xxx.etsimport { webview } from '@kit.ArkWeb';import { BusinessError } from '@kit.BasicServicesKit';import { promptAction } from '@kit.ArkUI';@Entry@Componentstruct WebComponent {  controller: webview.WebviewController = new 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 {      webview.WebviewController.setWebDebuggingAccess(true);    } catch (error) {      console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).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>

Web组件网页加载的性能指标

网页加载过程中需要关注一些重要的性能指标。例如,FCP(First Contentful Paint)首次内容绘制,FMP(First Meaningful Paint)首次有效绘制,LCP(Largest Contentful Paint)最大内容绘制等。Web组件提供了如下接口来通知开发者。

onFirstContentfulPaint 事件:网页首次内容绘制的回调函数。首次绘制文本、图像、非空白Canvva或者SVG的时间点。

onFirstMeaningfulPaint 事件:网页首次有效绘制的回调函数。首次绘制页面主要内容的时间点。

onLargestContentfulPaint 事件:网页绘制页面最大内容的回调函数。可视区域内容最大的可见元素开始出现在页面上的时间点。

鸿蒙全栈开发全新学习指南

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档用来跟着学习是非常有必要的。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

在这里插入图片描述

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:gitee.com/MNxiaona/733GH

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。关注小编,同时可以期待后续文章ing?,不定期分享原创知识。想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH


点击全文阅读


本文链接:http://zhangshiyu.com/post/166507.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1