网络上的错误方法
网络上有很多关于Volley使用的例子,由于大家都在偷懒,相互搬运代码,结果大多数例子都是在做错误的向导,来看Volley的两个参数Request, StringRequest与JsonObjectRequest,网上的传参例子如下:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
这对于StringRequest来说是没错的,但是对于JsonObjectRequest,如果用类似的方法:
JsonRequest<JSONObject> jsonRequest = new JsonObjectRequest(Method.POST,httpurl, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(TAG, "response -> " + response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
}
})
@Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json; charset=UTF-8");
return headers;
}
};
你会发现,传入的参数更不不起作用。
部分源码
来看JsonObjectRequest的代码:
public class JsonObjectRequest extends JsonRequest<JSONObject> {
public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, jsonRequest == null?null:jsonRequest.toString(), listener, errorListener);
}
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) {
this(jsonRequest == null?0:1, url, jsonRequest, listener, errorListener);
}
然后再看JsonRequest的代码:
public abstract class JsonRequest<T> extends Request<T> {
private static final String PROTOCOL_CHARSET = "utf-8";
private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", new Object[]{"utf-8"});
private final Listener<T> mListener;
private final String mRequestBody;
/** @deprecated */
public JsonRequest(String url, String requestBody, Listener<T> listener, ErrorListener errorListener) {
this(-1, url, requestBody, listener, errorListener);
}
public JsonRequest(int method, String url, String requestBody, Listener<T> listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mRequestBody = requestBody;
}
protected void deliverResponse(T response) {
this.mListener.onResponse(response);
}
protected abstract Response<T> parseNetworkResponse(NetworkResponse var1);
/** @deprecated */
public String getPostBodyContentType() {
return this.getBodyContentType();
}
/** @deprecated */
public byte[] getPostBody() {
return this.getBody();
}
public String getBodyContentType() {
return PROTOCOL_CONTENT_TYPE;
}
public byte[] getBody() {
try {
return this.mRequestBody == null?null:this.mRequestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException var2) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", new Object[]{this.mRequestBody, "utf-8"});
return null;
}
}
}
我们可以发现getBody与getPostBody已被重载,而参数只能从mRequestBody 中读取。在看Request相关代码部分:
public abstract class Request<T> implements Comparable<Request<T>> {
public byte[] getPostBody() throws AuthFailureError {
Map<String, String> postParams = this.getPostParams();
return postParams != null && postParams.size() > 0?this.encodeParameters(postParams, this.getPostParamsEncoding()):null;
}
protected Map<String, String> getParams() throws AuthFailureError {
return null;
}
从这可以看出之所以可以通过重载getParams()来设置参数,是因为getBody与getPostBody调用了它的关系,而在JsonRequest重载后,没有再调用getParams(),所以通过getParams()就无效了
正确方法
其实通过上面的源代码我们也知道对于JsonObjectRequest只能在构造函数中传入相关网络参数,例如:
Map<String, String> params = new HashMap<String, String>();
params.put("mobileNo", name);
params.put("pwd", password);
params.put("smsCode", code);
JSONObject jsonRequest = new JSONObject(params);
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, Config.REGISTER, jsonRequest, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(LOGTAG, response.toString());
try {
int status = response.getInt("status");
if(status == 200) {
saveLoginToken(response.getString("loginToken"));
gotoMainActivity();
}
} catch(JSONException jse) {
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(LOGTAG, "Error: " + error.getMessage());
Toast.makeText(RegisterActivity.this, "Register Fail:" + error.getMessage(), Toast.LENGTH_SHORT).show();
}