鴻蒙學習實戰之路 - 應用間鏈接最佳實踐
應用間鏈接是實現應用間無縫交互的關鍵技術,合理使用可以顯著提升用户體驗
關於本文
本文基於華為官方文檔整理,結合實際開發經驗,提供 HarmonyOS 應用間鏈接的實用指南
華為開發者聯盟 - 應用間鏈接概述
- 本文並不能代替官方文檔,所有內容基於官方文檔+實踐記錄
- 所有代碼示例都有詳細註釋,建議自己動手嘗試
- 基本所有關鍵功能都會附上對應的文檔鏈接,強烈建議你點看看看
- 本文將通過實際案例介紹應用間鏈接的實現方式和最佳實踐
代碼測試環境
確保你的開發環境符合以下要求:
|
軟件/工具
|
版本要求
|
|
HarmonyOS SDK
|
API Level 11+
|
|
TypeScript
|
5.0+
|
|
DevEco Studio
|
4.1+
|
|
設備要求
|
支持 HarmonyOS NEXT 的真機或模擬器
|
概述
應用間鏈接是指在不同應用之間建立通信和交互的技術。在 HarmonyOS 中,應用間鏈接主要通過以下幾種方式實現:
- App Linking:系統級深度鏈接,支持直接跳轉到應用內指定頁面
- startAbility:通過能力啓動實現應用間跳轉
- Web 攔截跳轉:在 Web 場景下實現應用間跳轉
應用場景示例
社交分享跳轉
- 用户 A 在社交應用中看到一篇文章,通過分享功能發送給好友 B
- 好友 B 點擊鏈接後,直接打開社交應用並定位到該篇文章,而非應用首頁
廣告跳轉
- 視頻應用中播放汽車商城應用的促銷廣告
- 點擊廣告後直接打開電商應用並跳轉至促銷活動頁面,用户無需在應用內搜索或導航
特殊文本識別跳轉
- 聊天界面識別到電話號碼
- 用户點擊電話號碼後直接打開系統撥號界面,方便用户撥打電話
本文將從以下幾個方面介紹 HarmonyOS 應用間鏈接的最佳實踐:
- App Linking 的基本概念和使用方法
- startAbility 實現應用間跳轉
- Web 攔截跳轉的實現方式
- 應用間鏈接的安全考慮
- 實際案例分析
1. App Linking 基本概念和使用
1.1 什麼是 App Linking
App Linking(應用鏈路)是 HarmonyOS 操作系統提供的一項系統級深度鏈接功能,它允許用户通過 HTTPS 鏈接直接跳轉到應用中的指定頁面,無論應用是否已安裝。
1.2 App Linking 的優勢
- 統一鏈接:同一個鏈接可以在不同平台和場景下使用
- 跨應用跳轉:支持在不同 HarmonyOS 應用之間無縫跳轉
- 靈活配置:可以自定義鏈接的行為和參數
- 用户體驗好:無需用户手動查找應用,直接跳轉至目標頁面
- 延遲鏈接:支持應用安裝後恢復之前的跳轉意圖
基於安全性和用户體驗的全面考量,建議優先採用 App Linking 技術。與 Deep Linking 相比,App Linking 提供了更高的安全性,避免了仿冒風險,並提升了用户在應用間跳轉時的整體使用體驗。
1.3 實現 App Linking
1.3.1 配置應用鏈接信息
在 module.json5 中配置應用鏈接信息:
{
module: {
name: "entry",
type: "entry",
description: "應用入口模塊",
mainElement: "EntryAbility",
deviceTypes: ["phone", "tablet"],
distro: {
deliveryWithInstall: true,
moduleName: "entry",
moduleType: "entry",
},
abilities: [
{
name: "EntryAbility",
srcEntry: "./ets/entryability/EntryAbility.ts",
description: "應用入口能力",
icon: "$media:icon",
label: "應用間鏈接示例",
startWindowIcon: "$media:icon",
startWindowBackground: "$color:start_window_background",
skills: [
{
entities: ["entity.system.home"],
actions: ["action.system.home"],
},
{
actions: ["ohos.want.action.viewData"],
uris: [
{
scheme: "https",
host: "example.com",
path: "/app/*",
},
],
},
],
},
],
},
}
1.3.2 處理鏈接跳轉
在 EntryAbility.ts 中處理鏈接跳轉:
import { UIAbility, Want, AbilityConstant } from "@kit.AbilityKit";
import { hilog } from "@kit.PerformanceAnalysisKit";
import { Configuration } from "@kit.ConfigurationKit";
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, "EntryAbility", "%{public}s", "Ability onCreate");
// 處理應用鏈接跳轉
this.handleAppLinking(want);
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, "EntryAbility", "%{public}s", "Ability onNewWant");
// 處理新的應用鏈接跳轉
this.handleAppLinking(want);
}
// 處理應用鏈接跳轉的方法
private handleAppLinking(want: Want) {
if (want.uri) {
hilog.info(
0x0000,
"EntryAbility",
"Received app linking: %{public}s",
want.uri
);
// 解析 URI 參數
const url = new URL(want.uri);
const path = url.pathname;
const params = new URLSearchParams(url.search);
// 根據路徑和參數執行相應操作
if (path.startsWith("/app/detail")) {
const id = params.get("id");
if (id) {
// 跳轉到詳情頁
this.context.startAbility({
bundleName: this.context.applicationInfo.bundleName,
abilityName: "DetailAbility",
parameters: {
itemId: id,
},
});
}
}
}
}
onDestroy() {
hilog.info(0x0000, "EntryAbility", "%{public}s", "Ability onDestroy");
}
onWindowStageCreate(windowStage: any) {
// 設置主頁面
windowStage.loadContent("pages/Index", (err, data) => {
if (err.code) {
hilog.error(
0x0000,
"EntryAbility",
"Failed to load content: %{public}s",
JSON.stringify(err)
);
return;
}
});
}
// 其他生命週期方法...
}
1.3.3 發起 App Linking 跳轉
在其他應用中發起 App Linking 跳轉:
import { businessError } from "@kit.BasicServicesKit";
import { openLink } from "@kit.LinkKit";
// 發起應用鏈接跳轉
async function launchAppLinking() {
try {
await openLink({
url: "https://example.com/app/detail?id=12345",
});
console.log("App linking launched successfully");
} catch (error) {
console.error("Failed to launch app linking:", error as businessError);
}
}
2. 使用 startAbility 實現應用間跳轉
2.1 startAbility 概述
startAbility 是 HarmonyOS 提供的一種能力啓動機制,可以用於在不同應用之間跳轉,支持傳遞複雜參數。
2.2 實現應用間跳轉
2.2.1 配置能力信息
在目標應用的 module.json5 中配置能力信息:
{
module: {
abilities: [
{
name: "DetailAbility",
srcEntry: "./ets/abilities/DetailAbility.ts",
description: "詳情頁能力",
icon: "$media:icon",
label: "詳情頁",
skills: [
{
actions: ["ohos.want.action.detailView"],
entities: ["entity.system.default"],
},
],
},
],
},
}
2.2.2 發起能力跳轉
在源應用中發起能力跳轉:
import { context } from "@kit.ArkUI";
import { businessError } from "@kit.BasicServicesKit";
// 發起應用間能力跳轉
async function startOtherAbility() {
try {
await context.startAbility({
bundleName: "com.example.targetapp",
abilityName: "DetailAbility",
action: "ohos.want.action.detailView",
parameters: {
itemId: "12345",
itemName: "示例商品",
itemPrice: 99.9,
},
});
console.log("Ability launched successfully");
} catch (error) {
console.error("Failed to launch ability:", error as businessError);
}
}
2.2.3 接收能力參數
在目標應用的 DetailAbility.ts 中接收參數:
import { UIAbility, Want, AbilityConstant } from "@kit.AbilityKit";
import { hilog } from "@kit.PerformanceAnalysisKit";
export default class DetailAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, "DetailAbility", "%{public}s", "Ability onCreate");
// 接收參數
if (want.parameters) {
const itemId = want.parameters.itemId;
const itemName = want.parameters.itemName;
const itemPrice = want.parameters.itemPrice;
hilog.info(
0x0000,
"DetailAbility",
"Received params: id=%{public}s, name=%{public}s, price=%{public}f",
itemId,
itemName,
itemPrice
);
// 保存參數,供頁面使用
this.context.abilityInfo.parameters = want.parameters;
}
}
// 其他生命週期方法...
}
3. Web 攔截跳轉
3.1 Web 攔截跳轉概述
Web 攔截跳轉是指在應用中加載 Web 頁面時,攔截特定的 URL 請求並跳轉到應用內的相應頁面。
3.2 實現 Web 攔截跳轉
import { Web } from '@kit.ArkUI';
import { WebviewController } from '@kit.ArkUI';
import { context } from '@kit.ArkUI';
@Entry
@Component
struct WebPage {
private webviewController: WebviewController = new WebviewController();
build() {
Column() {
Web({
src: 'https://example.com',
controller: this.webviewController
})
.javaScriptAccess(true)
.onUrlLoadIntercept((event) => {
const url = event.url;
// 攔截特定 URL
if (url.startsWith('https://example.com/app/')) {
// 解析 URL 參數
const urlObj = new URL(url);
const path = urlObj.pathname;
const params = new URLSearchParams(urlObj.search);
// 根據路徑跳轉到應用內頁面
if (path.startsWith('/app/detail')) {
const id = params.get('id');
if (id) {
// 跳轉到詳情頁
router.pushUrl({
url: `pages/DetailPage?id=${id}`
});
}
}
// 阻止默認的 URL 加載
return true;
}
// 允許其他 URL 正常加載
return false;
})
}
}
}
4. 應用間鏈接的安全考慮
4.1 驗證鏈接來源
在處理應用間鏈接時,應該驗證鏈接的來源和完整性,防止惡意鏈接攻擊。
// 驗證鏈接來源
private validateLink(url: string): boolean {
try {
const urlObj = new URL(url);
// 驗證域名
const allowedDomains = ['example.com', 'trusted-domain.com'];
if (!allowedDomains.includes(urlObj.host)) {
console.error('Invalid domain:', urlObj.host);
return false;
}
// 驗證路徑
if (!urlObj.pathname.startsWith('/app/')) {
console.error('Invalid path:', urlObj.pathname);
return false;
}
return true;
} catch (error) {
console.error('Invalid URL:', error);
return false;
}
}
4.2 限制敏感操作
對於涉及敏感操作的鏈接,應該要求用户確認或進行身份驗證。
// 處理敏感操作鏈接
private handleSensitiveLink(url: string) {
if (url.includes('/app/payment')) {
// 要求用户確認
promptAction.showDialog({
title: '支付確認',
message: '您確定要進行支付操作嗎?',
buttons: [
{ text: '取消', color: '#FF0000' },
{ text: '確認', color: '#007DFF' }
]
}).then(result => {
if (result.index === 1) {
// 用户確認後執行支付操作
this.processPayment(url);
}
});
}
}
5. 應用間鏈接最佳實踐總結
5.1 選擇合適的鏈接方式
|
鏈接方式
|
適用場景
|
優勢
|
|
App Linking
|
需要跨平台、跨應用的統一鏈接
|
統一鏈接,用户體驗好
|
|
startAbility
|
需要傳遞複雜參數的應用間跳轉
|
參數傳遞靈活,功能強大
|
|
Web 攔截跳轉
|
Web 頁面中的應用內跳轉
|
無縫集成 Web 和原生頁面
|
5.2 設計原則
- 簡潔明瞭:鏈接地址應該簡潔易記,避免複雜的參數
- 一致性:同一功能的鏈接在不同場景下應該保持一致
- 可測試性:鏈接應該易於測試和調試
- 可擴展性:鏈接設計應該考慮未來功能擴展的需要
5.3 性能優化
- 減少參數大小:避免在鏈接中傳遞過大的參數
- 異步處理:鏈接處理邏輯應該異步執行,避免阻塞主線程
- 緩存機制:對於頻繁訪問的鏈接,可以考慮使用緩存
結語
應用間鏈接是 HarmonyOS 應用開發中的重要技術,可以顯著提升應用間的交互體驗。本文介紹了三種主要的應用間鏈接方式:App Linking、startAbility 和 Web 攔截跳轉,並提供了詳細的實現代碼和最佳實踐。
希望本文的內容能夠對你有所幫助,祝你在鴻蒙開發之路上越走越遠!
參考文檔:
- 華為開發者聯盟 - 應用間鏈接概述
- HarmonyOS API 參考 - LinkKit
- HarmonyOS API 參考 - AbilityKit