寫在前面:本文基於 HarmonyOS Next 的摸爬滾打經驗總結。技術這東西更新快,如果哪裡說得不對,或者你有更厲害的操作,歡迎在評論區拍磚交流。轉載請註明出處,謝啦。
做移動端開發,最煩的是什么?是應用像一個個孤島,互相都不通氣。
用戶在微信裡點個鏈接,想跳到你的 App 裡看詳情,結果要麼沒反應,要麼跳出一堆甚至都沒聽說過的 App 讓你選。這就很尷尬了。為了解決這個問題,鴻蒙系統給我們提供了兩把鑰匙:一把叫 Deep Linking,一把叫 App 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 不再用那些亂七八糟的自定義協議,而是直接用標準的 HTTPS 鏈接(比如 https://www.example.com)。
這裡有個核心邏輯:域名校驗。系統會去驗證:“你這個 App 到底是不是這個域名的親兒子?”
這就特別適合做社交分享、廣告引流,或者短信召回老用戶。
這玩意兒需要“双向奔赴”:App 端要認領域名,伺服器端要認領 App。
伺服器端搞個“介紹信”:
你得在你的网站伺服器根目錄下,創建一個 .well-known/applinking.json 文件。這文件里寫啥?寫你 App 的身份證號(APP ID)。
這是為了告訴全天下:這個 App 是我罩著的。
App 端開啟“雷達”:
在 AGC 控制台開通服務後,你得在 module.json5 裡也配上 skills,不過這次 scheme 必須是 https。
注意:在 AGC 後台(增長 > App Linking)記得把“域名校驗”的開關打開,不然系統懶得去查。
配置好了,怎麼觸發跳轉呢?咱們看代碼。
鴻蒙提供了 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 裡顯得有點“復古”了。
不管是 Deep Linking 還是 App Linking,進了你的門,處理邏輯是樣的。都是在 Ability 的 onCreate 或者 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 依然是個輕量級的好選擇。
行了,關於鴻蒙的“連接藝術”今天就聊到這。代碼寫完了記得多測試,別到時候用戶點開鏈接一臉懵逼,那就尷尬了。