本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前API12)的技术细节,基于实际开发实践进行总结。
主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。
本文为原创内容,任何形式的转载必须注明出处及原作者。

引言
ArkWeb 是华为鸿蒙系统提供的一个强大的 Web 应用框架,允许开发者将 Web 页面嵌入到鸿蒙应用中,并与之进行交互。它可以极大地降低开发成本,提升开发效率,并实现跨平台的 Web 应用开发。ArkWeb 支持多种使用场景,例如:

应用集成 Web 页面: 应用可以在页面中使用 Web 组件,嵌入 Web 页面内容,以降低开发成本,提升开发、运营效率。
浏览器网页浏览场景: 浏览器类应用可以使用 Web 组件,打开三方网页,使用无痕模式浏览 Web 页面,设置广告拦截等。
小程序: 小程序类宿主应用可以使用 Web 组件,渲染小程序的页面。
Web 组件的生命周期
ArkWeb 的 Web 组件提供了丰富的生命周期回调接口,开发者可以通过这些接口感知 Web 组件的生命周期状态变化,并进行相关的业务处理。Web 组件的状态主要包括:
Controller 绑定到 Web 组件: 当 Controller 成功绑定到 Web 组件时触发该回调,推荐在此事件中注入 JS 对象、设置自定义用户代理等。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  Web({
    // ...
    .onControllerAttached(() => {
      // 推荐在此 loadUrl、设置自定义用户代理、注入 JS 对象等
      console.log('onControllerAttached execute');
    })
    // ...
  })
}

}
}
网页加载开始: 网页开始加载时触发该回调,推荐在此回调中执行 JavaScript 脚本 loadUrl 等。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  Web({
    // ...
    .onPageBegin((event) => {
      if (event) {
        console.log('onPageBegin url:' + event.url);
      }
    })
    // ...
  })
}

}
}
网页加载进度: 告知开发者当前页面加载的进度。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  Web({
    // ...
    .onProgressChange((event) => {
      if (event) {
        console.log('newProgress:' + event.newProgress);
      }
    })
    // ...
  })
}

}
}
网页加载结束: 网页加载完成时触发该回调,推荐在此回调中执行 JavaScript 脚本。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  Web({
    // ...
    .onPageEnd((event) => {
      if (event) {
        console.log('onPageEnd url:' + event.url);
      }
    })
    // ...
  })
}

}
}
页面即将可见: 在创建自定义组件的新实例后,在执行其 build 函数前执行,建议在此设置 WebDebug 调试模式、设置 Web 内核自定义协议 URL 的跨域请求与 fetch 请求的权限、设置 Cookie 等。
@Entry
@Component
struct WebComponent {
// ...
aboutToAppear(): void {

try {
  webview.WebviewController.setWebDebuggingAccess(true);
} catch (error) {
  console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
}

}
build() {

Column() {
  // ...
}

}
}
应用渲染进程异常退出: 应用渲染进程异常退出时触发该回调,可以在此回调中进行系统资源的释放、数据的保存等操作。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onRenderExited((event) => {
    if (event) {
      console.log('onRenderExited reason:' + event.renderExitReason);
    }
  })
  // ...
}

}
}
组件卸载消失: 组件卸载消失时触发此回调。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onDisAppear(() => {
    promptAction.showToast({
      message: 'The web is hidden',
      duration: 2000
    });
  })
  // ...
}

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

onFirstContentfulPaint: 网页首次内容绘制的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onFirstContentfulPaint(event => {
    if (event) {
      console.log("onFirstContentfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstContentfulPaintMs]:" + event.firstContentfulPaintMs);
    }
  })
  // ...
}

}
}
onFirstMeaningfulPaint: 网页首次有效绘制的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onFirstMeaningfulPaint(event => {
    if (event) {
      console.log("onFirstMeaningfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstMeaningfulPaintMs]:" + event.firstMeaningfulPaintMs);
    }
  })
  // ...
}

}
}
onLargestContentfulPaint: 网页绘制页面最大内容的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onLargestContentfulPaint(event => {
    if (event) {
      console.log("onLargestContentfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [largestContentfulPaintMs]:" + event.largestContentfulPaintMs);
    }
  })
  // ...
}

}
}
管理位置权限
ArkWeb 提供了位置权限管理能力。开发者可以通过 onGeolocationShow() 接口对某个网站进行位置权限管理。Web 组件根据接口响应结果,决定是否赋予前端页面权限。获取设备位置,需要开发者配置 ohos.permission.LOCATION、ohos.permission.APPROXIMATELY_LOCATION、ohos.permission.LOCATION_IN_BACKGROUND,并同时在设备上打开应用的位置权限和控制中心的位置信息。

@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  .onGeolocationShow((event) => { // 地理位置权限申请通知
    AlertDialog.show({
      title: '位置权限请求',
      message: '是否允许获取位置信息',
      primaryButton: {
        value: 'cancel',
        action: () => {
          if (event) {
            event.geolocation.invoke(event.origin, false, false); // 不允许此站点地理位置权限请求
          }
        },
      },
      secondaryButton: {
        value: 'ok',
        action: () => {
          if (event) {
            event.geolocation.invoke(event.origin, true, false); // 允许此站点地理位置权限请求
          }
        },
      },
    });
  })
  // ...
}

}
}
管理 Cookie 及数据存储
Cookie 是网络访问过程中,由服务端发送给客户端的一小段数据。客户端可持有该数据,并在后续访问该服务端时,方便服务端快速对客户端身份、状态等进行识别。当 Cookie SameSite 属性未指定时,默认值为 SameSite=Lax,只在用户导航到 cookie 的源站点时发送 cookie,不会在跨站请求中被发送。

@Entry
@Component
struct WebComponent {
// ...
build() {

Column() {
  // ...
  Button('configCookieSync')
    .onClick(() => {
      try {
        webview.WebCookieManager.configCookieSync('https://www.example.com', 'value=test');
      } catch (error) {
        console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
      }
    })
  // ...
}

}
}
缓存与存储管理
在访问网站时,网络资源请求是相对比较耗时的。开发者可以通过 Cache、Dom Storage 等手段将资源保存到本地,以提升访问同一网站的速度


SameX
1 声望2 粉丝