美文网首页
Android Uri query异常分析

Android Uri query异常分析

作者: 1琥珀川1 | 来源:发表于2018-12-28 21:34 被阅读12次

    起因

    有这样一个需求 我们想把 原始uri中的scheme转换一下 你会怎么做

    hehe://a/hehe?params=%7B%22url
    

    转换成

    haha://a/hehe?params=%7B%22url
    

    直接replace显然是不合适的

    经过

    我们这样做

     Uri originaluri = Uri.parse("hehe://a/hehe?params=%7B%22url");
     Uri newuri = new Uri.Builder().scheme("haha")
                    .authority(originaluri.getAuthority())
                    .path(originaluri.getPath())
                    .query(originaluri.getQuery()).build();
     Log.d("uri", newuri.toString());
    

    看似很美好但是日志确实

    haha://a/hehe?params%3D%7B%22url
    

    可以看出query参数中的 = 被编码了 变成了%3D!
    这显然不是我们想要的

    分析

    originaluri.getQuery()的返回结果是{"url
    那我们需要分析

    query(originaluri.getQuery()).build();
    

    都做了啥?

    最终会生成Part类作为uri的一个属性

    new Part(encoded, decoded) 
    

    该类存放我们query参数中的编码数据和解码数据,其中encoded = NOT_CACHED ,decoded = {"url.

    build()方法会返回HierarchicalUri类 我们看看该类的toString做了啥

     String encodedAuthority = authority.getEncoded();
                if (encodedAuthority != null) {
                    // Even if the authority is "", we still want to append "//".
                    builder.append("//").append(encodedAuthority);
                }
    
                String encodedPath = path.getEncoded();
                if (encodedPath != null) {
                    builder.append(encodedPath);
                }
    
                if (!query.isEmpty()) {
                    builder.append('?').append(query.getEncoded()); //编码 把query的所有数据的编码了
                }
    
       String getEncoded() {
                @SuppressWarnings("StringEquality")
                boolean hasEncoded = encoded != NOT_CACHED;
                return hasEncoded ? encoded : (encoded = encode(decoded));
            }
    

    builder.append('?').append(query.getEncoded());编码 由于没有缓存所以把query的解码数据编码了 所有 = 变成了 %3D

    结果

    如何解决呢?编码数据由缓存就可以了!

     Uri originaluri = Uri.parse("hehe://a/hehe?params=%7B%22url");
     Uri newuri = new Uri.Builder().scheme("haha")
                    .authority(originaluri.getAuthority())
                    .path(originaluri.getPath())
                    .encodedQuery(originaluri.getEncodedQuery()).build();
     Log.d("uri", newuri.toString());
    

    将 query改成encodedQuery就可以了

    相关文章

      网友评论

          本文标题:Android Uri query异常分析

          本文链接:https://www.haomeiwen.com/subject/tdtylqtx.html