鸿蒙NEXT开发【Web和应用的跳转与拉起】应用框架开发

概述

在使用ArkTS与Web进行混合开发时,应用内的部分页面使用了前端相关能力进行了开发,再使用Web组件进行了页面加载,在这种场景下涉及到从Web加载的页面向其他页面跳转,以及从Web页面拉起应用。本文也将从这两方面介绍Web页面跳转以及拉起应用相关的知识:

Web页面与ArkTS页面互相跳转

Web页面跳转Web页面

开发者在做Hybrid App混合开发时,Web页面的跳转可以直接在前端侧使用HTML提供的a标签来进行跳转,修改href为跳转后的地址即可,参考代码如下:

<a href="www.example.com">跳转到其他页面</a>

ArkTS页面跳转Web页面

在HarmonyOS应用开发中,会有Web页面和ArkTS页面互相之间进行跳转的场景,例如列表页用了ArkTS进行开发,而详情页设计上只有简单的内容展示并没有复杂的逻辑操作,于是使用了Web开发并使用了ArkTS中的Web组件进行了加载,在这种场景下,从列表页跳转到详情页就是从ArkTS页面跳转到Web页面,在这种场景下,开发者只需要在ArkTS页面对应的事件回调函数中使用路由栈提供的跳转功能即可实现。

NavDestination() {
  Column() {
    Button($r('app.string.back_to_web_page'))
      .width('100%')
      .height(40)
      .onClick(() => {
        this.navPathStack.pushPath({ name: 'WebPage' });
      })
  }
  // ...
}
.title('ArkTS页面')

Web页面跳转ArkTS页面

同样的,开发者也会有从Web页面跳转到ArkTS页面的场景,例如刚刚的场景中我希望返回到ArkTS页面,就是从Web页面跳转回ArkTS页面的场景,在这种场景下,实现步骤如下:

  1. 在HTML页面内使用a标签的href属性自定义跳转链接。

    <a class="function_item" href="arkts://pages/toOriginPage">跳转到ArkTS页面</a>
    

    说明

    开发者可以根据业务场景自行定义href,此处的定义的href并不作为a标签跳转后的地址,而是会在ArkTS侧进行跳转拦截,当检测到该链接时执行自定义逻辑。

  2. 然后在Web页面中,需要在onLoadIntercept中进行跳转拦截,获取跳转的url,如果与自定义的跳转链接一致,那么可以使用路由栈进行原生的页面跳转。

Navigation(this.navPathStack) {
  Column() {
    Web({
      src: $rawfile('index.html'),
      controller: this.controller
    })
      .zoomAccess(false)
      .onLoadIntercept((event) => {
        const url: string = event.data.getRequestUrl();
        if (url === 'arkts://pages/toOriginPage') {
          this.navPathStack.pushPath({ name: 'OriginPage' });
        }
        // ...
      })
  }
}

Web页面拉起应用

Web页面拉起系统应用页面

从Web页面拉起系统应用界面,也是一个常见的场景,例如开发者有发布图片的需求,而且图片上传的界面在前端界面已经有了实现并且做了多端适配,现在希望复用原有的界面,但是具体的图片选择的逻辑以及上传的逻辑希望修改成ArkTS侧的实现。实现步骤如下:

  1. 在Web页面内配置跳转的链接地址。此处使用a标签并不意味着上传的HTML元素就是a标签,而是以它为例,理论上开发者可以用任何HTML元素绑定onClick事件,通过设置window.location.href属性进行页面跳转。

    <a class="function_item" href="photo://pages/selectPhoto">拉起系统应用</a>
    
  2. 接着使用ArkTS侧提供的照片选择Picker进行图片的选择以及后续逻辑的开发。

Navigation(this.navPathStack) {
  Column() {
    Web({
      src: $rawfile('index3.html'),
      controller: this.controller
    })
      .zoomAccess(false)
      .onLoadIntercept((event) => {
        const url: string = event.data.getRequestUrl();
        if (url === 'photo://pages/selectPhoto') {
          const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
          photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
          photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目
          let uris: Array<string> = [];
          const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
          photoViewPicker.select(photoSelectOptions)
            .then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
              uris = photoSelectResult.photoUris;
              console.info('photoViewPicker.select to file succeed and uris are:' + uris);
            })
            .catch((err: BusinessError) => {
              console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
            })
        }
        return url !== 'resource://rawfile/index3.html';
      })
  }
}
.hideTitleBar(true)
.navDestination(this.PageMap)

Web页面拉起三方应用

开发者在HarmonyOS应用内使用了Web页面做了部分页面的实现,同时出于推广,或者需要在其他应用内处理一些逻辑等目的,需要拉起其他的三方应用,例如跳转到支付应用进行支付,在这些场景下,就需要用到拉起三方应用的相关知识,首先在实现方案上,拉起三方应用建议使用如下两种方案:

  1. 使用[Deep Linking]实现应用拉起。
  2. 使用[App Linking]实现应用拉起。

方案1:使用Deep Linking。

  1. 在目标方配置module.json5文件,保证entities中包含entity.system.browsable、actions中包含ohos.want.action.viewData,最后再配置uris,用户可以自定义scheme,host,port以及path。
{
  "module": {
    // ...
    "abilities": [
      {
        // ...
        "skills": [
          {
            "entities": [
              // ...
              "entity.system.browsable"
            ],
            "actions": [
              // ...
              "ohos.want.action.viewData"
            ],
            "uris": [
              {
                "scheme": "appScheme", // scheme可以自定义
                "host": "www.test.com", // host须配置关联的域名
                "port": "80", // port可选
                "path": "path1" // path可选,为了避免匹配到多个应用,建议配置该字段
              }
            ]
          }
        ],
      }
    ],
    // ...
  }
}
  1. 在调用方的module.json5文件中配置[querySchemes],标识允许当前应用进行跳转查询的URL schemes。
  "querySchemes": [
    "appScheme"
  ],
  1. 根据目标方的uris配置拼凑出完整的link地址,拼接方式为:scheme://host:port/path

    const link: string = "appScheme://www.test.com:80/path1";
    
  2. 通过[canOpenLink]接口判断link是否可以打开,如不能打开链接开发者可以自定义响应逻辑,此处直接返回。

  if (!bundleManager.canOpenLink(link)) {
    return;
  }
  1. 配置拉起时的启动参数openLinkOptions,在该配置中可以进行参数传递以及配置appLinkingOnly属性。代码参考如下:
Navigation(this.navPathStack) {
  Column() {
    Web({
      src: $rawfile('index2.html'),
      controller: this.controller
    })
      .zoomAccess(false)
      .onLoadIntercept((event) => {
        const url: string = event.data.getRequestUrl();
        if (url === 'third-party://pages/toThirdApp') {
          const link: string = "appScheme://www.test.com:80/path1";
          if (!bundleManager.canOpenLink(link)) {
            return;
          }
          const openLinkOptions: OpenLinkOptions = {
            appLinkingOnly: false,
            parameters: {
              name: 'test'
            }
          };
          this.context.openLink(link, openLinkOptions).then(() => {
            console.info('open link success.');
          }).catch((err: BusinessError) => {
            console.error(`open link failed. Code is ${err.code}, message is ${err.message}`);
          })
        }
        return url !== 'resource://rawfile/index2.html';
      })
  }
}

方案2:当开发者希望无论应用是否已安装,用户都可以访问到链接对应的内容,当应用安装时优先打开应用去呈现内容;当应用未安装时,则打开浏览器呈现Web版的内容,就可以使用App Linking的方式

总结:Deep Linking适用于需要在已安装的应用之间进行跳转,实现相对简单,但当无应用匹配时用户体验不佳。而App Linking适用于社交分享、广告引流等需要外部链接访问应用的场景,以及对安全性和用户体验要求较高的场景。AppLinking在Deep Linking的基础上增加了域名校验,提高了链接的安全性和可靠性,且无论应用是否安装,用户都能访问内容,缺点是实现相对复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值