Android Studio中使用volley请求数据后返回数据显示乱码的问题

在使用volley请求数据发现返回的数据中文显示乱码,以前的项目我是在Eclipse使用volley没发现什么问题,所以开始我以为是Android Studio的文件或工程编码设置和build.gradle的编译编码设置的问题,在反复统一修改成了utf-8后,发现还是在android log 控制台输出的中文是乱码。

分析过程

(1) 先用Android日志类输出中文,在Android Log 控制台是正常显示中文的,
说明与 Android Studio 没有关系。

(2) 然后用在线调试工具 http://apistore.baidu.com/astore/toolshttpproxy 调试接口,
发现服务端返回结果是正常显示
其中 Response Header

HTTP/1.1 200 OK
    Server: Tengine
    Date: Fri, 03 Jul 2015 14:57:49 GMT
    Content-Type: text/html;Charset=UTF-8
    Transfer-Encoding: chunked
    Connection: keep-alive
    Set-Cookie: CL_ECSCP_ID=bc44b20bc122138f888721b18bc6767b2694d7f4; path=/

其中 Response Body 显示的中文是正常显示的,说明服务端返回的中文至少是没什么问题

那么很有可能是我的网络请求工具volley在得到服务端的返回对结果进行编码转换出问题了,volley 在哪里且以什么样的编码对返回结果进行转换了呢?

带着这个问题我首先做了检查动作:
将正常显示的中文以ISO-8859-1弄成乱码,发现和在android log 控制台显示的乱码是一个样子,
这样进一步说明很有可能是volley将服务端返回的中文(Eg: utf-8格式)以 iso-8859-1 的形式封装成了string,那就成乱码了

我们正常处理方法应该以对应的编码进行封装, 服务端返回是utf-8,那么封装string就应该以utf-8封装
Eg:

byte[] data = response.getByte();
String result = String(data,"UTF-8");

那么volley 在出现编码转换的是在哪呢? 这就是接下来要找的根源,我们来分析volley源码:

首先我使用volley发送的请求是StringRequest类型,通过查看volley的源码,可以知道 volley中所有的请求Request<?> 是在 NetworkDispatcher(Thread的子类)进行分发和处理的:

(1) 我们直接查看它的run方法,里面是循环从请求队里mQueue中take一个req
(2)得到req后然后调用BasicNetWork(NetWork的实现类)的performRequest方法对Request进行处理

(3) performRequest(Request<> request) 方法 内部
执行的是mHttpStack的performRequest()方法,返回结果是通过封装成
NetworkResponse进行返回的

(4) 然后针对network的performRequest返回结果NetworkResponse
调用Request 的parseNetworkResponse 方法进行回调处理。

这里是StringRequest,它的parseNetworkResponse方法主要处理:
构造string,然后通过回调dataresponse进行返回

new String(response.data,HttpHeaderParser.parseCharset(response.headers))

在构造String的时候,第二个参数 编码使用的是HttpHeaderParser的parseCharset方法返回的编码。
parseCharset方法做的事就是解析出header中的编码,内部处理是:

(a) 在header中去找Content-Type,
(b) 然后找它的charset(全小写的charset),找到了charset就把对应的值(编码)返回

if(pair.length == 2 && pair[0].equals("charset"))

(c) 没有找到就返回 默认编码ISO-8859-1用来构造String

这里跟踪代码或通过在线API调试工具发现:服务端返回的response
header中Content-Type中的Charset(大写的C),所以没有找到charset,那么默认ISO-8859-1,那么new String(data,”IOS-8859-1”) 就会显示乱码

解决办法

问题原因和出现问题的地方找到了,那么接下来要做的就是怎样解决了?
有两种解决途径:

(1) 修改服务端:服务端返回的header中的Content-Type中的charset要全小写

(2) 服务端不修改, 那么就修改volley的源码重新编译, 兼容大小写 charset,Charset

修改volley 源码,找到 HttpHeaderParser 的 parseCharset 方法

 if(pair.length == 2 && pair[0].equals("charset"))

修改成 pair[0].toLower().equals(“charset”)

编译重新打volley jar包。

总结

这个问题主要责任在服务端,没有严格按照http协议标准来(返回的消息头Content-Type中的charset 不是全拼小写),而volley是按照http标准来处理的。 如果一开始我们就通过API 在线调试工具查看到Response Header 发现Content-Type …;Charset=UTF-8 这个问题,那么就不会花这么长时间去分析volley源码了。
其实本文章跟Android Studio 没关系,在Eclipse下也会出现同样的问题 :)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值