Kể từ phiên bản 1.2.0, Navigation 3 hỗ trợ liên kết sâu đến các đích đến trong ứng dụng bằng cách sử dụng các lớp DeepLinkRequest và DeepLinkMatcher.
Để hỗ trợ đường liên kết sâu trong ứng dụng, hãy hoàn tất các bước sau:
- Xác định bộ lọc ý định trong
AndroidManifest.xmlđể chỉ định những URI mà ứng dụng của bạn có thể xử lý. - Tạo các thực thể
DeepLinkMatcherđể liên kết các yêu cầu đến với các phím điều hướng của bạn. - So khớp các yêu cầu đến trong phương thức
onCreatehoặconNewIntentcủa hoạt động và cập nhật ngăn xếp lui cho phù hợp.
Tạo một DeepLinkRequest
DeepLinkRequest đại diện cho một đường liên kết sâu đến. Nó chứa một DeepLinkUri và RequestExtras không bắt buộc có thêm thông tin, chẳng hạn như hành động theo ý định hoặc loại MIME.
// Create a request with a String URI val request = DeepLinkRequest(uri = "https://www.example.com/home") // Create a request from a DeepLinkUri val deepLinkUri = DeepLinkUri("https://www.example.com/home") val requestFromUri = DeepLinkRequest(uri = deepLinkUri) // Create a request with a URI and action val requestWithAction = DeepLinkRequest( uri = "https://www.example.com/home", extras = DeepLinkRequest.actionExtra("android.intent.action.VIEW") ) // Create a request with URI, action and mimeType val requestWithMimeType = DeepLinkRequest( uri = "https://www.example.com/image", extras = requestExtras { put(DeepLinkRequest.ActionExtrasKey, "android.intent.action.VIEW") put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "image/png") } )
Cung cấp DeepLinkRequest nội dung bổ sung
Để lưu trữ thông tin bổ sung liên quan đến đường liên kết sâu, hãy sử dụng lớp RequestExtras. Để giúp việc xác định và tạo thực thể cho các thành phần bổ sung trở nên an toàn về kiểu, thư viện cung cấp giao diện RequestExtrasKey và DSL requestExtras.
Ngoài ra, thư viện còn cung cấp hai khoá bổ sung và trình trợ giúp liên quan:
MimeTypeExtrasKey: Dùng để lưu trữ loại MIMEString.ActionExtrasKey(chỉ dành cho Android): Dùng để lưu trữ hành độngStringcủaIntent.
val extras: RequestExtras = requestExtras { put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "application/json") put(DeepLinkRequest.ActionExtrasKey, Intent.ACTION_VIEW) } // Access typed values using the get operator val mimeType: String? = extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] val action: String? = extras[DeepLinkRequest.ActionExtrasKey] // Create extras using helper functions and combine them val mimeTypeExtras: RequestExtras = DeepLinkRequest.mimeTypeExtra("application/json") val combinedExtras: RequestExtras = extras + DeepLinkRequest.actionExtra(Intent.ACTION_VIEW)
Để xác định các thành phần bổ sung tuỳ chỉnh của riêng bạn, hãy triển khai giao diện RequestExtrasKey bằng một kiểu chung:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
Bạn cũng có thể sử dụng emptyRequestExtras() để tạo một thực thể trống hoặc kết hợp các thành phần bổ sung bằng toán tử + (plus) và - (minus).
Tạo DeepLinkRequest từ Intent
Trên Android, bạn có thể tạo DeepLinkRequest ngay từ Intent. Khi được xây dựng theo cách này, DeepLinkRequest sẽ được tạo như sau:
uriđược sao chép từ trườngdatacủa ý định.- Nếu không rỗng, loại MIME và thông tin bổ sung của hành động sẽ được đặt từ các trường ý định tương ứng.
- Tất cả
intent.extrascó giá trị không rỗng đều được lưu dưới dạngSavedStatetrongDeepLinkRequest.IntentExtrasKey. - Mọi dữ liệu bổ sung được cung cấp bằng tham số
extrasđều được thêm vào.
object CampaignIdExtrasKey : RequestExtrasKey<String> val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://www.example.com/item/42") type = "application/json" putExtra("user_id", "123") } val request = DeepLinkRequest( intent = intent, extras = requestExtras { put(CampaignIdExtrasKey, "spring_promo") } ) // The resulting DeepLinkRequest contains: val uri = request.uri // "https://www.example.com/item/42" val action = request.extras[DeepLinkRequest.ActionExtrasKey] // "android.intent.action.VIEW" val mimeType = request.extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] // "application/json" val intentExtras: SavedState? = request.extras[DeepLinkRequest.IntentExtrasKey] val userId: String? = intentExtras?.read { getStringOrNull("user_id") } // "123" val campaignId: String? = request.extras[CampaignIdExtrasKey] // "spring_promo"
Tạo các thực thể DeepLinkMatcher
DeepLinkMatcher liên kết các thực thể DeepLinkRequest đến với các khoá điều hướng có thể thêm vào ngăn xếp lui của ứng dụng. Navigation 3 cung cấp 3 trình so khớp tích hợp sẵn: UriDeepLinkMatcher để so khớp URI dựa trên mẫu, StaticKeyDeepLinkMatcher cho các đường liên kết cơ bản và BackStackMatcher để tạo ngăn xếp lui tổng hợp. Thư viện này cũng hỗ trợ trình so khớp tuỳ chỉnh cho các trường hợp sử dụng không được trình so khớp tích hợp sẵn hỗ trợ.
Để biết thêm thông tin, hãy xem phần Tạo DeepLinkMatcher.
Thêm bộ lọc ý định
Để cho phép đường liên kết sâu bắt đầu hoạt động, bạn phải xác định các phần tử <intent-filter> phù hợp trong AndroidManifest.xml của ứng dụng. Để biết thêm thông tin, hãy xem phần Thêm bộ lọc ý định cho đường liên kết đến.
So khớp yêu cầu đến
Sau khi tạo các thực thể DeepLinkMatcher, bạn có thể so khớp các yêu cầu đến trong hoạt động của mình.
Để so khớp một yêu cầu đến, hãy hoàn tất các bước sau:
- Tạo thực thể cho các thực thể
DeepLinkMatcher. - Sắp xếp tất cả các thực thể
DeepLinkMatcher, một cách rõ ràng hoặc bằng cách sử dụng multibindings (đa liên kết). - Tạo
DeepLinkRequesttừIntentsắp tới. - So khớp yêu cầu với tất cả trình so khớp và tìm kết quả phù hợp nhất.
- Tạo ngăn xếp lui từ kết quả khớp.
// 1. Instantiate your DeepLinkMatcher instances. val homeMatcher = StaticKeyDeepLinkMatcher(HomeKey, listOf(DeepLinkMatcher.actionFilter(Intent.ACTION_VIEW))) val userProfileMatcher = UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ).withBackStack { matchResult -> listOf(HomeKey, matchResult.key) } val telMatcher = TelDeepLinkMatcher() // 2. Collate all of your DeepLinkMatcher instances. // Note: Collating matchers with different generic types requires wildcards, // erasing the specific generic types. val deepLinkMatchers: List<DeepLinkMatcher<*, *>> = listOf( homeMatcher, userProfileMatcher, telMatcher ) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // 3. Create a DeepLinkRequest from the incoming Intent val request = DeepLinkRequest(intent = intent) // 4. Match the request against all matchers and find the best match. // Because DeepLinkMatcher.MatchResult implements Comparable, you can // use maxOrNull() to find the best match. val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } // List<DeepLinkMatcher.MatchResult<*>> .maxOrNull() // DeepLinkMatcher.MatchResult<*>? // 5. Create the back stack from the match result (or fall back to a default). val backStack: List<NavKey> = when (matchResult) { // If no match is found, use the default back stack (e.g., HomeKey) null -> listOf(HomeKey) // If a BackStackMatchResult is found, use the back stack from the result is BackStackMatchResult<*, *> -> { // Because star-projected matchers erase the key type, cast the back stack to List<NavKey>. @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } // Otherwise, use the key from the match result to make a single-item back stack else -> listOf(matchResult.key as NavKey) } } }