写在前面:本文基于 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 标签去"抢注"这个暗号。
json
// 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。
- 服务器端搞个"介绍信" : 你得在你的网站服务器根目录下,创建一个
.well-known/applinking.json文件。这文件里写啥?写你 App 的身份证号(APP ID)。 这是为了告诉全天下:这个 App 是我罩着的。 - App 端开启"雷达" : 在 AGC 控制台开通服务后,你得在
module.json5里也配上 skills,不过这次 scheme 必须是https。 注意:在 AGC 后台(增长 > App Linking)记得把"域名校验"的开关打开,不然系统懒得去查。
三、 实战:到底怎么跳?
配置好了,怎么触发跳转呢?咱们看代码。
场景 A:我想拉起别人(发起方)
鸿蒙提供了 openLink 接口,这比传统的 startAbility 更适合处理链接跳转。
typescript
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,进了你的门,处理逻辑是一样的。都是在 Ability 的 onCreate 或者 onNewWant 里接客。
typescript
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 依然是个轻量级的好选择。
行了,关于鸿蒙的"连接艺术"今天就聊到这。代码写完了记得多测测,别到时候用户点开链接一脸懵逼,那就尴尬了。