鸿蒙实现APP和网页跳转方案总结

发布于:2025-09-09 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、网页跳转至 APP(鸿蒙设备)

1. App Linking
维度 要求
域名 仅支持 HTTPS,且末尾禁止出现 /
校验文件 https://<domain>/.well-known/applinking.json
签名 必须「手动签名」,自动签名会导致域名校验失败

applinking.json(部分示例)

{
  "applinking": {
    "apps": [
      { "appIdentifier": "1058xxxxx" }   // AGC 上看的 APP ID
    ]
  }
}

module.json5(关键片段)

"skills": [
  {
    "entities": ["entity.system.browsable"],
    "actions": ["ohos.want.action.viewData"],
    "uris": [
      { "scheme": "https", "host": "www.example.com", "pathPattern": ".*" }
    ],
    "domainVerify": true
  }
]

接收侧 ArkTS(EntryAbility.ets)

onCreate(want: Want): void {
  const uri = want?.uri?.toString();
  if (uri) {
    // 跳详情页(router 在 18 仍可用)
    const params = uri.split('?')[1];
    AppStorage.set('deeplink', params);
    windowStage.loadContent('pages/Detail');
  }
}

网页侧(纯 HTML)

<a href="https://www.example.com/detail?sku=10086">在 App 打开</a>

若设备未装 App,系统会退回到浏览器打开同一地址;如 AGC 里勾选了「直达应用市场」,则直接跳「应用市场详情页」并携带「延迟链接」,安装后首次启动仍可还原到 sku=10086 详情页。


2. Deep Linking(自定义 scheme,仅作兼容)
优点 零服务端配置
缺点 1. 未安装时无法 fallback;2. 易被拦截;3. 需要额外弹窗提示

module.json5

"uris": [{ "scheme": "demo", "host": "detail" }]

网页

<a href="demo://detail?sku=10086">打开 Demo App</a>

Deep Linking 不会触发域名校验,因此不会与 App Linking 冲突,可二者共存。


二、APP 跳转至网页(官方推荐)

1. 内嵌 ArkWeb(最常用)
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebPage {
  ctrl = new webview.WebviewController();
  build() {
    Column() {
      Web({ src: 'https://www.example.com', controller: this.ctrl })
        .onLoadIntercept(e => {
          // 如果想拦截外链可在此做路由
          return false;
        });
    }
  }
}
2. 系统浏览器/Custom Tabs(一次性跳出)
import { browser } from '@kit.ArkTS';
browser.loadCustomTabsUrl({
  url: 'https://www.example.com',
  options: { toolbarColor: '#FF6200EE' }
});

无需申请额外权限;loadCustomTabsUrl 在 API 18 仍然为「华为私有接口」,非 OHOS 联盟规范,但已稳定开放。


三、双向数据通信(ArkWeb ⇄ ArkTS)

1. URL 参数(单向,网页→App)
2. JSBridge(双向,推荐)

App 侧注册

this.ctrl.registerJavaScriptProxy({
  // 供网页调用的句柄
  nativePay: (orderJson: string) => {
    console.info('网页下单:' + orderJson);
    // TODO 调起支付 SDK
    return JSON.stringify({ code: 0 });
  }
}, 'HarmonyBridge');

网页侧调用

<script>
  window.HarmonyBridge.nativePay(JSON.stringify({sku:10086}));
</script>

App → Web

this.ctrl.runJavaScript(`refreshData('${JSON.stringify(newData)}')`);

注意:注入对象必须在 onPageEnd 之后才可被 window 访问;复杂类型请先 JSON.stringify 后传输,否则会出现「类型丢失」。


四、网页下载监听(断点续传/进度/异常)

this.ctrl.setDownloadDelegate({
  onBeforeDownload: (item: webview.WebDownloadItem) => {
    item.setDownloadPath('/storage/media/100/local/files/');
    item.start();          // 返回 true 即继续,false 可阻断
  },
  onDownloadUpdated: (item) => {
    console.info(`进度=${item.getPercentComplete()}%`);
  },
  onDownloadFailed: (item) => {
    console.error(`失败=${item.getErrorCode()}`);
  }
});

权限:ohos.permission.INTERNET + ohos.permission.WRITE_MEDIA(官方API 18+ 已合并到 WRITE_MEDIA,不再需要 WRITE_USER_STORAGE,请注意)。


五、特殊场景答疑

  1. 多 App 同时关联同一域名
    系统会弹出「选择框」;如想静默直达,可在 path/pathRegex 里做区分,例如
    /shop/* → 电商 App,/video/* → 短视频 App。

  2. 原服务(元服务)
    与普通 App 完全一致,同样走 App Linking;只是入口 UIAbilitylaunchType 需为 singleton

  3. 首次开机 20 min 内无法拉起
    系统初次域名校验未完成,可重启或连网后等待 24 h 重试。


网站公告

今日签到

点亮在社区的每一天
去签到