网络上有很多关于Volley使用的例子,由于大家都在偷懒,相互搬运代码,结果大多数例子都是在做错误的向导,来看Volley的两个参数Request, StringRequest与JsonObjectRequest,网上的传参例子如下:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map getParams() throws AuthFailureError {
Map map = new HashMap();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
这对于StringRequest来说是没错的,但是对于JsonObjectRequest,如果用类似的方法:
JsonRequest jsonRequest = new JsonObjectRequest(Method.POST,httpurl, null,
new Response.Listener() {
@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 getHeaders() {
HashMap headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json; charset=UTF-8");
return headers;
}
};
你会发现,传入的参数更不不起作用。
来看JsonObjectRequest的代码:
public class JsonObjectRequest extends JsonRequest {
public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener listener, ErrorListener errorListener) {
super(method, url, jsonRequest == null?null:jsonRequest.toString(), listener, errorListener);
}
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener listener, ErrorListener errorListener) {
this(jsonRequest == null?0:1, url, jsonRequest, listener, errorListener);
}
然后再看JsonRequest的代码:
public abstract class JsonRequest extends Request {
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 mListener;
private final String mRequestBody;
/** @deprecated */
public JsonRequest(String url, String requestBody, Listener listener, ErrorListener errorListener) {
this(-1, url, requestBody, listener, errorListener);
}
public JsonRequest(int method, String url, String requestBody, Listener 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 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 implements Comparable> {
public byte[] getPostBody() throws AuthFailureError {
Map postParams = this.getPostParams();
return postParams != null && postParams.size() > 0?this.encodeParameters(postParams, this.getPostParamsEncoding()):null;
}
protected Map getParams() throws AuthFailureError {
return null;
}
从这可以看出之所以可以通过重载getParams()来设置参数,是因为getBody与getPostBody调用了它的关系,而在JsonRequest重载后,没有再调用getParams(),所以通过getParams()就无效了
其实通过上面的源代码我们也知道对于JsonObjectRequest只能在构造函数中传入相关网络参数,例如:
Map params = new HashMap();
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() {
@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();
}