החל מגרסה 1.2.0, Navigation 3 תומך בקישורי עומק ליעדים באפליקציה באמצעות המחלקות DeepLinkRequest ו-DeepLinkMatcher.
כדי לתמוך בקישורי עומק באפליקציה, צריך לבצע את השלבים הבאים:
- מגדירים מסנני Intent ב-
AndroidManifest.xmlכדי לציין אילו מזהי URI האפליקציה יכולה לטפל בהם. - יוצרים
DeepLinkMatcherמופעים כדי למפות בקשות נכנסות למקשי הניווט. - התאמה של בקשות נכנסות בשיטה
onCreateאוonNewIntentשל הפעילות ועדכון של מקבץ הפעילויות הקודמות (back stack) בהתאם.
צור 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 בלבד): משמש לאחסון פעולה שלIntentString.
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של הכוונה. - אם הערך לא 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-filter> התואמים בקובץ AndroidManifest.xml של האפליקציה. מידע נוסף זמין במאמר הוספת מסנני Intent לקישורים נכנסים.
התאמה של בקשה נכנסת
אחרי שיוצרים את מופעי DeepLinkMatcher, אפשר להתאים בקשות נכנסות לפעילות.
כדי להתאים בקשה נכנסת:
- יוצרים מופעים של
DeepLinkMatcher. - אוספים את כל המכונות של
DeepLinkMatcher, באופן מפורש או באמצעות multibindings. - יצירת
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) } } }