使用androidx.navigation库时含斜杠地址导航崩溃问题
问题场景
- 自定义
NavType<Address?>传递地址数据时,街道名称不含斜杠(如Green Street 1)的地址可正常完成导航 - 街道名称含斜杠(如
Green Street 1/3)的地址会触发「目标不存在」错误,直接导致应用崩溃 - 根因是AndroidX Navigation底层基于URL的导航机制,斜杠是URL路径的分隔符,序列化后的JSON字符串中的斜杠会破坏导航路径的解析逻辑
解决方案
方案1:对序列化字符串做URL编码/解码
通过编码将斜杠转换为URL安全的格式,避免被Navigation误解析为路径分隔符,解码时再还原为原始字符串。修改后的AddressType实现如下:
import android.os.Bundle import androidx.navigation.NavType import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import java.net.URLDecoder import java.net.URLEncoder @Serializable data class Address( val city: String?, val companyId: Int, val country: String?, val gpsCoordinates: String?, val id: Int, val pointName: String? = null, val pointType: String, val postalCode: String?, val street: String? ) val AddressType = object : NavType<Address?>(isNullableAllowed = true) { override fun get(bundle: Bundle, key: String): Address? { return bundle.getString(key)?.takeIf { it != "null" } ?.let { URLDecoder.decode(it, "UTF-8") } ?.let { Json.decodeFromString<Address>(it) } } override fun parseValue(value: String): Address? { return if (value == "null") { null } else { URLDecoder.decode(value, "UTF-8") .let { Json.decodeFromString<Address>(it) } } } override fun serializeAsValue(value: Address?): String { return Json.encodeToString(value) .let { URLEncoder.encode(it, "UTF-8") } } override fun put(bundle: Bundle, key: String, value: Address?) { bundle.putString( key, Json.encodeToString(value) .let { URLEncoder.encode(it, "UTF-8") } ) } }
方案2:使用Safe Args传递数据(推荐)
如果项目已集成Navigation Safe Args,可直接用它传递自定义序列化对象,完全避开URL解析的问题:
- 在模块的
build.gradle中启用Safe Args插件:
plugins { id "androidx.navigation.safeargs.kotlin" }
- 在NavGraph的目标页面中定义参数:
<argument android:name="address" app:argType="com.yourpackage.Address" />
- 通过生成的方向类完成导航和参数接收:
// 发起导航时传递地址 val action = HomeFragmentDirections.actionHomeToDetail(address) findNavController().navigate(action) // 目标页面接收地址 val args = DetailFragmentArgs.fromBundle(requireArguments()) val address = args.address
原理说明
- Navigation在处理导航参数时,会将参数值拼接到类URL的路径结构中,斜杠会被识别为路径分隔符,导致参数被截断或解析失败
- URL编码将特殊字符(如
/)转换为%2F,确保Navigation不会误解析,解码后可还原为原始字符串 - Safe Args底层通过Bundle传递序列化对象,完全绕开了URL解析逻辑,是更稳定可靠的实现方式
内容的提问来源于stack exchange,提问作者Cuyer
相关产品推荐
相关产品推荐

