Jetpack Compose导航能否使用相对URL实现深度链接?
解决方案:Jetpack Compose中使用相对URL实现带参数的深度链接
问题根源
直接使用纯相对路径(如/screen-3/{title})作为深度链接的uriPattern时,Navigation组件无法正确解析带参数的URI结构——深度链接匹配依赖完整的URI格式(scheme://host/path),单纯的相对路径带参数无法触发参数提取逻辑,导致跳转失败。
方案一:使用deepLinkPrefixes统一配置前缀(推荐)
Jetpack Navigation 2.4.0及以上版本提供了deepLinkPrefixes参数,可给整个NavHost统一配置所有需要支持的基础URI前缀。这样每个页面只需声明相对路径的深度链接,完美适配多Scheme/Host和模块化场景。
修改后的核心代码:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyApplicationTheme { val navController = rememberNavController() NavHost( navController = navController, startDestination = "screen-1", // 统一配置所有需要支持的基础前缀 deepLinkPrefixes = setOf( "https://www.myurl.com", "myscheme://app" ) ) { composable( "screen-1", deepLinks = listOf( navDeepLink { uriPattern = "/screen-1" action = Intent.ACTION_VIEW } ) ) { Column { Text("Screen 1") Button( onClick = { navController.navigate("screen-3/hello") } ) { Text("Navigate to Screen 3!!!") } } } composable( "screen-2", deepLinks = listOf( navDeepLink { uriPattern = "/screen-2" action = Intent.ACTION_VIEW } ) ) { Text("Screen 2") } composable( "screen-3/{title}", arguments = listOf( navArgument("title") { type = NavType.StringType } ), deepLinks = listOf( navDeepLink { uriPattern = "/screen-3/{title}" action = Intent.ACTION_VIEW } ) ) { backStackEntry -> val title = backStackEntry.arguments?.getString("title") Text("Screen 3 - $title") } } } } }
方案二:使用通配符覆盖Scheme和Host
如果无法升级Navigation版本,可通过通配符匹配任意Scheme和Host,仅保留路径部分的匹配规则:
修改screen-3的深度链接配置:
composable( "screen-3/{title}", arguments = listOf( navArgument("title") { type = NavType.StringType } ), deepLinks = listOf( navDeepLink { // 用*匹配任意Scheme和Host,路径部分保留参数占位符 uriPattern = "*://*/screen-3/{title}" action = Intent.ACTION_VIEW } ) ) { backStackEntry -> val title = backStackEntry.arguments?.getString("title") Text("Screen 3 - $title") }
验证方法
使用adb命令测试深度链接:
# 测试自定义Scheme adb shell am start -W -a android.intent.action.VIEW -d "myscheme://app/screen-3/test_hello" com.your.package.name # 测试Web Scheme adb shell am start -W -a android.intent.action.VIEW -d "https://www.myurl.com/screen-3/test_world" com.your.package.name
两种方案都能实现:无需为每个页面重复声明多Scheme/Host的深度链接,模块化场景下各模块仅需维护相对路径即可。
内容的提问来源于stack exchange,提问作者user648462
相关产品推荐
相关产品推荐

