החל מגרסה 1.2.0, Navigation 3 תומך בקישורי עומק ליעדים באפליקציה באמצעות המחלקות DeepLinkRequest ו-DeepLinkMatcher.
כדי לתמוך בקישורי עומק באפליקציה, צריך לבצע את השלבים הבאים:
- מגדירים מסנני Intent בקובץ
AndroidManifest.xmlכדי לציין באילו מזהי URI האפליקציה יכולה לטפל. - יוצרים מכונות של
DeepLinkMatcherכדי למפות את הבקשות הנכנסות למקשי הניווט. - התאימו את הבקשות הנכנסות ב-method
onCreateאוonNewIntentשל הפעילות, ועדכנו את מקבץ הפעילויות הקודמות בהתאם.
צור DeepLinkRequest
הסמל DeepLinkRequest מייצג קישור עומק נכנס. הוא מכיל DeepLinkUri וRequestExtras אופציונלי עם מידע נוסף, כמו פעולת ה-Intent או סוג ה-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") } )
צריך לספק DeepLinkRequest תוספות
כדי לאחסן מידע נוסף שקשור לקישור העומק, משתמשים בכיתה RequestExtras. כדי להגדיר וליצור מופעים של תוספות בצורה שמונעת שגיאות הקלדה, הספרייה מספקת את הממשק RequestExtrasKey ואת ה-DSL requestExtras.
בנוסף, הספרייה מספקת שני מפתחות נוספים ורכיבי עזר משויכים:
-
MimeTypeExtrasKey: משמש לאחסון סוג MIMEString. -
ActionExtrasKey(ב-Android בלבד): משמש לאחסוןStringשל פעולתIntent.
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)
כדי להגדיר תוספות מותאמות אישית משלכם, צריך להטמיע את הממשק RequestExtrasKey עם גנרי מוקלד:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
אפשר גם להשתמש ב-emptyRequestExtras() כדי ליצור מופע ריק, או לשלב תוספות באמצעות האופרטורים + (plus) ו-- (minus).
יצירת DeepLinkRequest מתוך Intent
ב-Android, אפשר ליצור DeepLinkRequest ישירות מ-Intent. כשהוא בנוי בצורה הזו, ה-DeepLinkRequest בנוי כך:
- הערך של
uriמועתק מהשדהdataשל ה-Intent. - אם הערך הוא לא null, סוג ה-MIME והתוספות של הפעולה מוגדרים משדות ה-Intent התואמים.
- כל הערכים של
intent.extrasשאינם null נשמרים בתורSavedStateב-DeepLinkRequest.IntentExtrasKey. - כל תוספת שסופקה באמצעות הפרמטר
extrasתתווסף.
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"
יצירת מכונות של DeepLinkMatcher
DeepLinkMatcher ממפה מופעים נכנסים של DeepLinkRequest למקשי ניווט שאפשר להוסיף למקבץ הפעילויות הקודמות (back stack) של האפליקציה. ב-Navigation 3 יש שלושה מתאמים מובְנים: UriDeepLinkMatcher להתאמת URI שמבוססת על תבניות, StaticKeyDeepLinkMatcher לקישורים בסיסיים ו-BackStackMatcher ליצירת מקבצי פעילויות קודמות סינתטיים. הספרייה תומכת גם בהתאמות בהתאמה אישית לתרחישים לדוגמה שלא נכללים בהתאמות המובנות.
מידע נוסף זמין במאמר יצירת DeepLinkMatchers.
הוספת מסנני Intent
כדי להפעיל קישור עומק שיתחיל את הפעילות, צריך להגדיר את רכיבי ה-<intent-filter> התואמים בקובץ AndroidManifest.xml של האפליקציה. מידע נוסף זמין במאמר הוספת מסנני Intent לקישורים נכנסים.
התאמה לבקשה נכנסת
אחרי שיצרתם את המכונות של DeepLinkMatcher, אתם יכולים להתאים בקשות נכנסות בפעילות שלכם.
כדי להתאים בקשה נכנסת, מבצעים את השלבים הבאים:
- יוצרים מופע של המכונות של
DeepLinkMatcher. - אוספים את כל המופעים של
DeepLinkMatcher, באופן מפורש או באמצעות קישורים מרובים. - יוצרים
DeepLinkRequestמה-Intentהנכנס. - התאמה של הבקשה לכל ההתאמות ומציאת ההתאמה הטובה ביותר.
- יוצרים את מקבץ הפעילויות הקודמות (back stack) מתוצאת ההתאמה.
// 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) } } }