阅读视图

发现新文章,点击刷新页面。

鸿蒙应用的“任意门”:Deep Linking 与 App Linking 的相爱相杀

写在前面:本文基于 HarmonyOS Next 的摸爬滚打经验总结。技术这东西更新快,如果哪里说得不对,或者你有更骚的操作,欢迎在评论区拍砖交流。转载请注明出处,谢啦。

做移动端开发,最烦的是什么?是应用像一个个孤岛,互相都不通气。

用户在微信里点个链接,想跳到你的 App 里看详情,结果要么没反应,要么跳出一堆甚至都没听说过的 App 让你选。这就很尴尬了。为了解决这个问题,鸿蒙系统给咱们提供了两把钥匙:一把叫 Deep Linking,一把叫 App Linking

很多兄弟容易搞混,觉得这俩不是一回事吗?确实,目的都是为了“跳转”,但手段和段位可大不一样。今天咱们就来扒一扒这两者的底裤。


一、 Deep Linking:简单粗暴的“土法炼钢”

Deep Linking 说白了,就是利用自定义协议(Scheme)来实现跳转。这招在移动开发界属于“老兵”了。

它是怎么工作的?

你想让别人通过暗号找到你,你就得先起个暗号。比如你做个地图 App,你可以跟系统喊一嗓子:“以后只要有人喊 geo:// 开头的,都归我管!”

这就是 Deep Linking 的核心:自定义 Scheme

  • 优点:门槛低,随便定义。my-super-app://,想怎么写怎么写。
  • 缺点:太随意了。万一隔壁老王也定义了 geo:// 怎么办?这时候系统就懵圈了,只能弹个窗让用户自己选。这一选,用户体验就断档了。而且这玩意儿不安全,谁都能冒充。

怎么配置?

在鸿蒙里,你得在 module.json5 里通过 skills 标签去“抢注”这个暗号。

// module.json5
{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "skills": [
          {
            "uris": [
              {
                "scheme": "mychat", // 你的暗号
                "host": "talk.com", // 具体的接头地点
                "path": "room"      // 具体的房间号
              }
            ]
          }
        ]
      }
    ]
  }
}

这一下,只要有链接是 mychat://talk.com/room,系统就会把目光投向你。


二、 App Linking:持证上岗的“正规军”

华为现在大力推的是 App Linking。为啥?因为它正规、安全、体验好。

它强在哪?

App Linking 不再用那些乱七八糟的自定义协议,而是直接用标准的 HTTPS 链接(比如 https://www.example.com)。

这里有个核心逻辑:域名校验。 系统会去验证:“你这个 App 到底是不是这个域名的亲儿子?”。

  • 如果验证通过:用户点击链接,直接拉起 App,没有任何弹窗干扰,丝般顺滑。
  • 如果没安装 App:既然是 HTTPS,那就直接用浏览器打开网页。这就叫“进可攻退可守”,用户永远不会看到 404 或者无响应。

这就特别适合做社交分享、广告引流,或者短信召回老用户。

怎么配置?(重点来了,这里稍微繁琐点)

这玩意儿需要“双向奔赴”:App 端要认领域名,服务器端要认领 App。

  1. 服务器端搞个“介绍信”: 你得在你的网站服务器根目录下,创建一个 .well-known/applinking.json 文件。这文件里写啥?写你 App 的身份证号(APP ID)。 这是为了告诉全天下:这个 App 是我罩着的。
  2. App 端开启“雷达”: 在 AGC 控制台开通服务后,你得在 module.json5 里也配上 skills,不过这次 scheme 必须是 https注意:在 AGC 后台(增长 > App Linking)记得把“域名校验”的开关打开,不然系统懒得去查。

三、 实战:到底怎么跳?

配置好了,怎么触发跳转呢?咱们看代码。

场景 A:我想拉起别人(发起方)

鸿蒙提供了 openLink 接口,这比传统的 startAbility 更适合处理链接跳转。

import { common } from '@ohos.app.ability.common';

// 比如在一个按钮点击事件里
function jumpToTarget(context: common.UIAbilityContext) {
  // 目标链接
  const targetLink = "https://www.example.com/programs?action=showall"; 
  
  const options: common.OpenLinkOptions = {
    // 重点!这里有个开关
    // true: 只要 App Linking(没安装App就可能没反应或者走浏览器逻辑,看系统实现)
    // false: 兼容 Deep Linking 模式,哪怕没校验过域名的 scheme 也能试着跳
    appLinkingOnly: false 
  };

  try {
    context.openLink(targetLink, options).then(() => {
      console.info('跳转成功,走你!');
    }).catch((err) => {
      console.error(`跳转翻车了: ${JSON.stringify(err)}`);
    });
  } catch (paramError) {
    console.error(`参数都有问题: ${JSON.stringify(paramError)}`);
  }
}

如果你非要用 Deep Linking 的那种 geo: 协议,用 startAbility 也是可以的,构建一个 Want 对象就行,但这在 API 12 里显得有点“复古”了。

场景 B:别人拉起我(接收方)

不管是 Deep Linking 还是 App Linking,进了你的门,处理逻辑是一样的。都是在 AbilityonCreate 或者 onNewWant 里接客。

import { UIAbility, Want, AbilityConstant } from '@ohos.app.ability.common';
import { url } from '@ohos.arkts';

export default class EntryAbility extends UIAbility {
  
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.handleLink(want);
  }

  // 如果 App 已经在后台活着,会走这里
  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.handleLink(want);
  }

  handleLink(want: Want) {
    const uri = want?.uri;
    if (!uri) return; // 没带链接?那是误触吧

    console.info(`收到链接请求: ${uri}`);

    // 解析 URL,这就跟前端解析 location.href 一个德行
    try {
      const urlObject = url.URL.parseURL(uri);
      const action = urlObject.params.get('action');
      
      if (action === "showall") {
        // 路由跳转逻辑:带大伙去“所有节目”页面
        // router.pushUrl(...) 
      }
    } catch (e) {
      console.error("这链接格式不对啊,老铁");
    }
  }
}


四、 总结:该选哪一个?

说了一大堆,最后给兄弟们来个“防纠结指南”:

特性 Deep Linking (土法) App Linking (正规军)
链接长相 myapp://detail https://www.myapp.com/detail
安全性 低 (谁都能用) 高 (域名校验,防伪冒)
没安装App时 报错或无响应 自动打开浏览器网页,体验无缝衔接
唯一性 不保证 (可能弹窗选App) 保证 (唯一归属,一键直达)
适用场景 App 内部页面互跳、非公网环境 外部引流、营销短信、二维码、社交分享

血泪建议: 如果是做对外推广、H5 唤醒 App,无脑上 App Linking。它是未来的主流,而且不用担心“应用未安装”的尴尬。 如果是 App 内部自己跳自己,或者公司内部几个 App 互通,不想搞服务器域名那一套,那 Deep Linking 依然是个轻量级的好选择。

行了,关于鸿蒙的“连接艺术”今天就聊到这。代码写完了记得多测测,别到时候用户点开链接一脸懵逼,那就尴尬了。

❌