之前Android开发一直用的是多层封装的Final框架。最近开始学习使用小巧的volley。
在使用该框架的过程中,出现了数次乱码问题,再次做以总结。
分别是返回数据乱码和提交参数乱码两个问题:
一、返回数据乱码
该乱码问题比较常见。
使用StringRequest时,返回数据乱码,观察StringRequest类下源码:
@Override protected Response<String> parseNetworkResponse(NetworkResponse response) { String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); }
发现字符集转换的语句是
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
进入改函数体:
public static String parseCharset(Map<String, String> headers, String defaultCharset) { String contentType = headers.get(HTTP.CONTENT_TYPE); if (contentType != null) { String[] params = contentType.split(";"); for (int i = 1; i < params.length; i++) { String[] pair = params[i].trim().split("="); if (pair.length == 2) { if (pair[0].equals("charset")) { return pair[1]; } } } } return defaultCharset; }
得知volley通过检查charset来判断字符集,若返回的header中没有charset,则采用默认的字符集"ISO-8859-1"
所以当服务器返回的header不规范时,会发生乱码。
解决方案:
最简单的是重写parseNetworkResponse函数,例如是GBK的话:
@Override protected Response<String> parseNetworkResponse(NetworkResponse response) { String str = null; try { str = new String(response.data, "gbk");//这里写死不好哦 } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return Response.success(str, HttpHeaderParser.parseCacheHeaders(response)); }
另外也可以是对源码进行修改,或者扩展StringRequest(这和重写区别不大)。
二、提交参数乱码
一些网站提交的参数采用GBK,而不是UTF-8,所以这导致在使用Volley上传参数时乱码。
观察Request<T>类的这个函数:
protected String getParamsEncoding() { return DEFAULT_PARAMS_ENCODING; }
该函数的作用是转换参数的编码类型。其中DEFAULT_PARAMS_ENCODING为utf-8,所以默认值未utf-8,当服务器的接受参数编码不为utf-8时发生乱码。
解决方案,例如GBK时:
@Override protected String getParamsEncoding() { return "GBK"; }
如此即可。