You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Uri.getQueryParameter无法获取带[]的查询参数值

问题原因

这是Android原生android.net.Uri类的历史逻辑不一致问题:

  • getQueryParameterNames()提取参数名时,会自动对URL编码字符做解码,因此可以正常返回解码后的page[size]参数名
  • getQueryParameter(String key)执行参数匹配时,会先对传入的key做URL编码,其中[会被转义为%5B、]会被转义为%5D,但内部匹配原始查询串的逻辑没有兼容未编码方括号的场景,最终转义后的key无法和原始串中的page[size]匹配,因此返回null。

该问题本质是Uri类的两个公开方法对URI保留字符[、]的编解码逻辑不对等,是存在多年的遗留实现bug。

可行解决方案
  • 无额外依赖的兼容方案:自行实现参数解析逻辑,绕过原生getQueryParameter的bug,直接从原始查询串拆分匹配参数,参考代码如下:
import android.net.Uri
import java.net.URLDecoder
import java.nio.charset.StandardCharsets

fun Uri.getQueryParameterSafe(key: String): String? {
    val rawQuery = encodedQuery ?: return null
    rawQuery.split("&").forEach { paramPair ->
        val splitIndex = paramPair.indexOf("=")
        val paramName = if (splitIndex > 0) {
            URLDecoder.decode(
                paramPair.substring(0, splitIndex),
                StandardCharsets.UTF_8.name()
            )
        } else {
            paramPair
        }
        if (paramName == key) {
            return when {
                splitIndex < 0 -> ""
                paramPair.length == splitIndex + 1 -> ""
                else -> URLDecoder.decode(
                    paramPair.substring(splitIndex + 1),
                    StandardCharsets.UTF_8.name()
                )
            }
        }
    }
    return null
}

// 调用示例
val uri = Uri.parse("/endpoint/path?query1=foo&page[size]=1")
val pageSize = uri.getQueryParameterSafe("page[size]") // 返回值为"1"
  • 若项目已引入OkHttp依赖,可直接使用OkHttp的HttpUrl类解析URL,该实现对带保留字符的查询参数处理符合RFC规范,不会出现匹配失败的问题。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:15:48