在 Android 中,深層連結是可讓您直接連往應用程式的特定目的地的連結。
瀏覽元件可讓您建立兩種不同的深層連結:明顯及隱含。
建立明確深層連結
明確深層連結是深層連結的一種單獨執行個體,會使用 PendingIntent
將使用者帶往應用程式中的特定位置。舉例來說,您可以在通知或應用程式小工具中顯示明確深層連結。
當使用者透過明確深層連結開啟應用程式時,系統會清除工作返回堆疊,並替換為深層連結的目的地。在建立巢狀結構圖時,每個巢狀結構層級的起始目的地也會新增至堆疊中 (即階層中每個 <navigation>
元素的起始目的地)。也就是說,當使用者按下深層連結目的地中的「Back」按鈕時,就會返回導覽堆疊,如同從進入點進入應用程式時一樣。
您可以使用 NavDeepLinkBuilder
類別建構 PendingIntent
,如下方範例所示。請注意,如果提供的內容並非 Activity
,建構函式則會使用 PackageManager.getLaunchIntentForPackage()
(如果有) 做為預設的啟動活動。
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent();
根據預設,NavDeepLinkBuilder
會以應用程式資訊清單中宣告的預設啟動 Activity
來啟動明確深層連結。如果 NavHost
處於其他的活動中,則必須在建立深層連結建構工具時指定其元件名稱:
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity::class.java) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity.class) .createPendingIntent();
如果已有 ComponentName
,可以直接將其傳送至建構工具:
Kotlin
val componentName = ... val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent()
Java
ComponentName componentName = ...; PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent();
如果您已有 NavController
,也可以使用 NavController.createDeepLink()
建立深層連結。
建立隱含深層連結
隱含深層連結是指應用程式中特定的目的地。在叫用深層連結時 (例如當使用者點擊連結時),Android 就可以將應用程式開啟至對應的目的地。
深層連結可依 URI、意圖動作及 MIME 類型進行比對符合。可以為單一的深層連結指定多個比對類型,但請注意,系統會優先比對 URI 引數,接著是操作,然後是 MIME 類型。
以下是含有 URI、操作及 MIME 類型的深層連結範例:
<fragment android:id="@+id/a"
android:name="com.example.myapplication.FragmentA"
tools:layout="@layout/a">
<deepLink app:uri="www.example.com"
app:action="android.intent.action.MY_ACTION"
app:mimeType="type/subtype"/>
</fragment>
您也可以使用瀏覽編輯器建立前往目的地的隱含深層連結,如下所示:
- 在導覽編輯器的「Design」分頁中,選取深層連結的目的地。
- 在「Attributes」面板的「Deep Links」部分中按一下「+」。
在隨即顯示的「Add Deep Link」對話方塊中,輸入深層連結的相關資訊。
請注意以下事項:
- 系統會將無配置的 URI 視為 http 或 https。例如,
www.google.com
可符合http://www.google.com
和https://www.google.com
兩者。 {placeholder_name}
格式的路徑參數預留位置符合一個或多個字元。例如,http://www.example.com/users/{id}
符合http://www.example.com/users/4
。瀏覽元件會嘗試比對預留位置名稱與定義的引數 (針對深層連結目的地所定義),從而將預留位置的值剖析為適當的類型。如果不具有定義相同名稱的引數,引數值會使用預設的String
類型。可以使用 .* 萬用字元來比對 0 個以上的字元。- 可以使用查詢參數預留位置來取代路徑參數,也可以搭配路徑參數使用。例如,
http://www.example.com/users/{id}?myarg={myarg}
符合http://www.example.com/users/4?myarg=28
。 - 使用預設值或空值定義的查詢變數參數預留位置則不需進行比對。舉例來說,
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}
與http://www.example.com/users/4?arg2=28
或http://www.example.com/users/4?arg1=7
相符。但具有路徑參數則否。舉例來說,http://www.example.com/users?arg1=7&arg2=28
並不符合上述模式,因為未提供必要路徑參數。 - 多餘的查詢參數不會影響深層連結 URI 比對。舉例來說,儘管 URI 模式中並未定義
extraneousParam
,http://www.example.com/users/{id}
也能與http://www.example.com/users/4?extraneousParam=7
相符。
- 系統會將無配置的 URI 視為 http 或 https。例如,
(選用) 勾選「Auto Verify」,要求 Google 驗證您是 URI 的擁有者。詳情請參閱「驗證 Android 應用程式連結」。
按一下「Add」。連結圖示 會顯示在所選目的地上方,表示該目的地設有深層連結。
按一下「Code」分頁標籤,切換至 XML 檢視畫面。具有巢狀結構的
<deepLink>
元素已新增至目的地:<deepLink app:uri="https://www.google.com" />
如要啟用隱含深層連結,還必須在應用程式的 manifest.xml
檔案中新增內容。將單一 <nav-graph>
元素新增至指向現有瀏覽圖的活動,如以下範例所示:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity name=".MainActivity" ...> ... <nav-graph android:value="@navigation/nav_graph" /> ... </activity> </application> </manifest>
建構專案時,Navigation 元件會將 <nav-graph>
元素替換成產生的 <intent-filter>
元素,以符合導覽圖中的所有深層連結。
觸發隱含深層連結時,返回堆疊的狀態取決於隱含式 Intent
是否透過 Intent.FLAG_ACTIVITY_NEW_TASK
旗標啟動:
- 如果設定了旗標,系統會清除工作返回堆疊,並以深層連結目的地取代。與明確深層連結一樣,在為圖表建立巢狀結構時,每個巢狀結構層級的起始目的地 (即階層中每個
<navigation>
元素的起始目的地) 也會新增至堆疊中。也就是說,當使用者按下深層連結目的地中的「Back」按鈕時,就會返回導覽堆疊,如同從進入點進入應用程式時一樣。 - 如未設定旗標,此時仍會停留在上個應用程式的工作堆疊中,這是觸發隱含深層連結的位置。在此情況下,「Back」按鈕會將使用者帶回到上一個應用程式,而「Up」按鈕則會在導覽圖的階層父項目的地上啟動應用程式的工作。
處理深層連結
使用瀏覽時,強烈建議您一律使用 standard
的預設 launchMode
。使用 standard
啟動模式時,瀏覽功能會自動處理深層連結,方法是呼叫 handleDeepLink()
,藉此處理 Intent
內的任何明確或隱含深層連結。不過,如果在使用替代的 launchMode
(例如 singleTop
) 時重新使用了 Activity
,系統並不會自動執行這項操作。在此情況下,必須在 onNewIntent()
中手動呼叫 handleDeepLink()
,如下例所示:
Kotlin
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) navController.handleDeepLink(intent) }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); navController.handleDeepLink(intent); }
其他資源
如要進一步瞭解導覽功能,請參閱下列資源。