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 của bạn 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. - 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ội dung này chứa DeepLinkUri và RequestExtras không bắt buộc cùng thông tin bổ sung, chẳng hạn như thao tác 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 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. Để xác định và khởi tạo các loại bổ sung an toàn về kiểu, thư viện này cung cấp giao diện RequestExtrasKey và DSL requestExtras.
Ngoài ra, thư viện này cung cấp 2 khoá bổ sung và các trợ giúp liên quan:
MimeTypeExtrasKey: Dùng để lưu trữ một loại MIMEString.ActionExtrasKey(chỉ dành cho Android): Dùng để lưu trữ thao tácIntentcủaString.
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ông tin 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 được nhập:
// 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ể dùng emptyRequestExtras() để tạo một thực thể trống hoặc kết hợp các phần bổ sung bằng cách dù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 tạo theo cách này, DeepLinkRequest sẽ có cấu trúc như sau:
uriđược sao chép từ trườngdatacủa ý định.- Nếu không phải là giá trị rỗng, loại MIME và thao tác extras sẽ được đặt từ các trường ý định tương ứng.
- Tất cả
intent.extrascó giá trị khác rỗng sẽ được lưu dưới dạngSavedStatetrongDeepLinkRequest.IntentExtrasKey. - Mọi thuộc tính bổ sung khác đượ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 phiên bản DeepLinkMatcher
DeepLinkMatcher ánh xạ các thực thể DeepLinkRequest đến các khoá điều hướng mà bạn có thể thêm vào ngăn xếp lui của ứng dụng. Navigation 3 cung cấp 3 đối tượng so khớp tích hợp: 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 quay lại giả. 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 hỗ trợ.
Để biết thêm thông tin, hãy xem phần Tạo DeepLinkMatchers.
Thêm bộ lọc ý định
Để cho phép một đường liên kết sâu khởi động hoạt động của bạn, 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 phiên bản
DeepLinkMatcher. - Đối chiếu tất cả các thực thể
DeepLinkMatchercủa bạn, một cách rõ ràng hoặc bằng cách sử dụng multibindings. - Tạo một
DeepLinkRequesttừIntentđến. - So khớp yêu cầu với tất cả các đối tượng 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ả so 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) } } }