Jetpack Compose Navigation传递含/的本地文件路径字符串报错
问题根因
Compose Navigation 默认将路由串中的 / 识别为路由层级分隔符。直接把包含大量 / 的绝对文件路径拼接在路由地址后,导航库会把路径中每一段斜杠分割的内容都当作独立路由节点解析,自然匹配不到预先定义的detail_screen路由目的地。这和测试结果完全吻合:不含 / 的普通字符串不会触发路由拆分,因此可以正常跳转。
可行修复方案
任选一种即可:
方案1:传参前做URL编码
传递路径前对字符串做URL编码,将/等特殊字符转义,导航库就不会将其识别为路由分隔符。
传参侧代码:import java.net.URLEncoder import java.nio.charset.StandardCharsets // 原始音频路径 val rawAudioPath = "/storage/emulated/0/Android/media/com.Slack/Notifications/Slack - Here you go.mp3" val encodedPath = URLEncoder.encode(rawAudioPath, StandardCharsets.UTF_8.name()) navController.navigate("detail_screen/$encodedPath")接收侧代码:
import java.net.URLDecoder import java.nio.charset.StandardCharsets import androidx.navigation.NavType import androidx.navigation.navArgument composable( route = "detail_screen/{audioPath}", arguments = listOf(navArgument("audioPath") { type = NavType.StringType }) ) { entry -> val encodedPath = entry.arguments?.getString("audioPath").orEmpty() val audioPath = URLDecoder.decode(encodedPath, StandardCharsets.UTF_8.name()) DetailScreen(audioPath = audioPath) }这个方案同时可以解决路径中包含空格、中文、其他特殊符号导致的路由匹配问题。
方案2:改用查询参数传递
不要把文件路径放在路由路径段,改为查询参数传递,Compose Navigation不会将查询参数内的/识别为路由分隔符,且框架会自动处理编解码,不需要手动调用编解码方法。
传参侧代码:val audioPath = "/storage/emulated/0/Android/media/com.Slack/Notifications/Slack - Here you go.mp3" navController.navigate("detail_screen?audioPath=$audioPath")接收侧代码:
composable( route = "detail_screen?audioPath={audioPath}", arguments = listOf(navArgument("audioPath") { type = NavType.StringType defaultValue = "" }) ) { entry -> val audioPath = entry.arguments?.getString("audioPath").orEmpty() DetailScreen(audioPath = audioPath) }方案3:绕开路由字符串传参(官方推荐,适配所有复杂参数)
如果后续还要传递更多带特殊字符的参数、或者大尺寸对象,不要把参数拼接在路由串里,直接通过BackStack的savedStateHandle传值,或者通过共享ViewModel持有数据,完全避开路由字符串解析逻辑,不会出现任何特殊字符导致的路由匹配问题。
内容的提问来源于stack exchange,提问作者iamkdblue
相关产品推荐
相关产品推荐

