鸿蒙ArkWeb深度解析:核心功能与隐藏技巧揭秘 原创

猫猫头啊
发布于 2025-3-25 20:30
3496浏览
0收藏

一、引言:鸿蒙ArkWeb的核心地位

在鸿蒙生态系统中,ArkWeb是H5页面渲染与混合开发的关键组件。尽管官方文档详细阐述了基础功能,但许多高级功能与性能优化技巧仍隐藏在“冰山之下”。本文将深入剖析ArkWeb的核心功能,并结合实战经验,揭秘那些官方文档中未明确提及的隐藏技巧。


二、核心功能解析

  1. Web页面加载

    ArkWeb不仅能加载远程或本地网页,还能与原生H5功能无缝对接,实现混合开发。在元服务中,ArkWeb还能替代RichText组件,加载富文本内容。

    import { webview } from '@kit.ArkWeb';
     
    @Entry
    @Component
    struct WebComponent {
      controller: webview.WebviewController = new webview.WebviewController();
     
      build() {
        Column() {
          // 加载本地资源文件
          Web({ src: $rawfile("index.html"), controller: this.controller })
          // 加载在线网页
          Web({ src: 'www.example.com', controller: this.controller})
        }
      }
    }
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.

    元服务中,RichText组件无法使用,可通过ArkWeb加载富文本内容:

    @State data: string = '...'; // 富文本内容
     
    Button('加载富文本').onClick((event: ClickEvent) => {
      this.controller.loadData(this.data, '', '')
    })
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.

鸿蒙ArkWeb深度解析:核心功能与隐藏技巧揭秘-鸿蒙开发者社区

  1. 支持的网络协议与资源类型

    ArkWeb支持HTTP/HTTPS协议及本地文件加载。但需注意,直接加载HTTP协议的内容可能出现白屏,需开启混合模式:

    .mixedMode(MixedMode.All)
    
    • 1.

    参考文档链接

  2. 页面生命周期与状态管理

    常见的生命周期回调包括onPageBeginonPageEndonControllerAttachedonProgressChange等。其中,onControllerAttached在加载中调用十分重要,controller的操作需在控制器绑定后才能继续,否则可能引起崩溃。当网络异常或网页不稳定时,onPageBegin的触发时机可能延迟,导致白屏现象。此时,可通过增加启动页等方案优化用户体验。

     Web({
          src: this.src,
          controller: this.controller,
        })
          .width('100%')
          .layoutWeight(1)
    	  .onControllerAttached(() => {
          })
          .onPageBegin((event: OnPageBeginEvent) => {
          })//页面开始加载
          .onPageEnd((event: OnPageEndEvent) => {
          })//页面加载结束
          .onProgressChange((event: OnProgressChangeEvent) => {
          })//页面加载的进度值
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
  3. 安全与权限控制

    • 敏感接口(如地理位置、摄像头)需通过onPermissionRequest、onGeolocationShow等回调向用户发起权限请求。

      位置权限申请之前geolocationAccess需要置为true,否则无法正常授权

     Web({
          src: this.src,
          controller: this.controller,
        })
          .width('100%')
          .layoutWeight(1)
          .geolocationAccess(true)//获取位置权限时要为true
          .onGeolocationShow(async (event: OnGeolocationShowEvent) => {
          this.webLocationPermissionManager.locationStateManage(this.quickEntry)
            event.geolocation.invoke(event.origin, true, false)
          })
          .onGeolocationHide(() => {
            if (this.quickEntry ? this.quickEntry.isGetLocation : false) {
              showToast('用户未同意获取地理位置信息')
              LogUtil.w(this.Tag, 'onGeolocationHide', '获取地理位置弹窗被取消')
            }
          })
         .onPermissionRequest((event: OnPermissionRequestEvent) => {//其他授权
            PermissionUtil.handleWebPermissionRequest(event.request)
          })
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.
    • 18.
    • 19.
    • 20.
    • 图片的下载和上传受鸿蒙安全策略限制,H5端不能直接对用户的图库进行操作,上传文件时选取图库资源时无法获取图片资源,这种情况可以在onShowFileSelector的回调中用图片选择器:photoAccessHelper接管处理
     Web({
          src: this.src,
          controller: this.controller,
        })
    	  .onShowFileSelector((event) => { //替代安全控件功能
            LogUtil.d('asda', event.result, event.fileSelector.getTitle(),
             event.fileSelector.getMode(),
             event.fileSelector.getAcceptType(),
             event.fileSelector.isCapture())
            if (this.hasIntersection(event.fileSelector.getAcceptType(),
             this.supportedExtensions)) {
              let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
              PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE
              PhotoSelectOptions.maxSelectNumber = this.selectPhotoMaxNumber
              PhotoSelectOptions.isOriginalSupported = true
              PhotoSelectOptions.subWindowName = '选择上传图片'
              const photoPicker = new photoAccessHelper.PhotoViewPicker()
              photoPicker.select(PhotoSelectOptions)
                .then(async (PhotoSelectResult) => {
                  if (PhotoSelectResult.photoUris.length === 0) {
                    console.warn('No image selected.')
                    return
                  }
                  const srcUri = PhotoSelectResult.photoUris[0]
                  let endings: string = this.extractFileExtension(srcUri) ? this.extractFileExtension(srcUri) as string : ''
                  const context = getContext(this) as common.UIAbilityContext
                  const destPath = `${context.tempDir}/` + Date.now() + `.` + endings
                 //存储图片操作
            return true
          })
    
    • 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.
    • ArkWeb的图片下载在混合开发中会存在一个坑点,onDownloadStart是官方提供的下载回调,但是这个功能在绝大部分的下载场景中是无法满足开发者们的需求的,遇到无法下载的情况可以通过webview.WebDownloadDelegate来接管实现,通过接管下载可实现对下载流程的控制,还可以通过安全控件SaveButton将下载的文件保存到图库中,下载功能的详细实现可以参考这篇文章,这里面有详细的demo和完整的代码:HarmonyOS混合开发–ArkWeb 文件下载接管快速实现HarmonyOS混合开发ArkWeb文件下载接管快 - 掘金
  4. 缓存与性能优化

    通过预解析、预连接、预加载、获取post请求、预编译生成编译缓存、离线资源免拦截注入等方法,可加速页面渲染。其中,离线资源免拦截注入对于卡顿或服务器访问慢的情况尤为有效,具体的实现可以参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/web-predictor-V5#。


三、官方文档不常见的隐藏技巧

  1. 高级调试技巧

    • 远程Chrome DevTools集成:通过chrome://inspect/#devices在浏览器中调试ArkWeb内页面。需开启调试模式,并配置端口映射。
    chrome://inspect/#devices
    
    • 1.

    打开调试模式

    aboutToAppear() {
      // 配置Web开启调试模式
      webview.WebviewController.setWebDebuggingAccess(true);
    }
    
    • 1.
    • 2.
    • 3.
    • 4.

    在命令行输入命令:hdc fport tcp:9222 localabstract:webview_devtools_remote_53206

    后面的数字对应的是相应的端口号,在日志的地方可以查看,多执行两次后就会出现web的加载情况。

鸿蒙ArkWeb深度解析:核心功能与隐藏技巧揭秘-鸿蒙开发者社区

鸿蒙ArkWeb深度解析:核心功能与隐藏技巧揭秘-鸿蒙开发者社区
鸿蒙ArkWeb深度解析:核心功能与隐藏技巧揭秘-鸿蒙开发者社区

  • 日志捕获与性能分析:通过onConsole回调将H5页面日志输出到dev,便于调试。
.onConsole((event) => {
  if (event) {
 LogUtil.d(this.Tag, 'onConsole', 'getMessage:', event.message.getMessage(), 'getSourceId:',
      event.message.getSourceId(), 'getLineNumber:', event.message.getLineNumber(), 'getMessageLevel:',
      event.message.getMessageLevel())
  }
  return false;
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  1. 特殊场景解决方案

    • 处理复杂手势冲突,如横向滚动与页面缩放。

    通过horizontalScrollBarAccessverticalScrollBarAccess控制滚动条状态,zoomAccess属性控制缩放、metaViewport配合页面变动实现窗口自适应布局

    Web({
      src: this.url,
      controller: this.controller,
    })
      .layoutWeight(1)
      .zoomAccess(false)//缩放控制
      .metaViewport(true)//窗口自适应
      .horizontalScrollBarAccess(false)//滚动条控制
      .verticalScrollBarAccess(false)//滚动条控制
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 适配暗黑模式与动态主题切换。
    .darkMode(WebDarkMode.Auto)//开启网页深色模式
    
    • 1.
    • ArkWeb视频全屏播放的兼容性处理 。

    通过onFullScreenEnteronFullScreenExit和窗口管理实现H5页面在鸿蒙中的全屏切换,切换时的屏幕适配要考虑到安全区域的溢出控制

          .onFullScreenEnter((event) => {
            //检测到全屏事件
            window.getLastWindow(getContext(), (err: BusinessError, data) => {
                  data?.setPreferredOrientation(window.Orientation.LANDSCAPE) 
              }
            })
          })
          .onFullScreenExit(() => { //检测到退出全屏事件
            this.handler?.exitFullScreen()
            window.getLastWindow(getContext(), (err: BusinessError, data) => {
            data?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED)
            })
          })
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.

四、结语:构建高效的混合开发生态

鸿蒙ArkWeb通过不断进化的技术架构,正在为开发者提供更强大的Web集成能力。本文揭示的多个核心技巧,均经过生产环境验证,可帮助开发者快速构建高性能混合应用,在混合开发和使用ArkWeb中最头疼的问题是突然的白屏和调试困难,下期将针对ArkWeb白屏处理方案和ArkWeb各个功能点调试方案进行分享。

本期分享代码仓库地址:代码仓库/ArkWebDemo

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-3-25 20:31:58修改
收藏
回复
举报


回复
    相关推荐