之前通过源码简单的了解一下Volley.
1.Volley源码学习笔记_RequestQueue和BasicNetWork
2.Volley源码学习笔记_ExecutorDelivery
3.Volley源码学习笔记_CacheDispatcher和NetworkDispatcher
4.Volley源码学习笔记_Request
现在我们可以尝试自定义一个Volley请求。可以适用一般的get,post(请求类型是String)以及图片上传。
用到的jar:volley.jar, httpmime-4.1.1.jar
继承Request,并实现他的2个方法,之前的源码解析中我们也看了这2个方法是干什么的。
public class MyVolleyRequest extends Request<String> {
//构造函数
public MyVolleyRequest(int method, String url, Response.ErrorListener listener) {
super(method, url, listener);
}
//对返回的数据进行解析
@Override
protected Response<String> parseNetworkResponse(NetworkResponse networkResponse) {
return null;
}
//返回请求成功的数据
@Override
protected void deliverResponse(String s) {
}
}
定义一些参数
private MultipartEntity entity ;//一些带有关文件参数和读取的类
private Map<String, String> header;//请求头信息
private Response.Listener<String> mListener;//请求成功的监听
private Response.ErrorListener mErrorListener;//请求错误的监听
private String bodyContentType;//文件类型
private Map<String, String> params;
private List<File> files;
private String fileName;//文件组相关的参数名称
private int kVolleyTimeOutMS=20*1000;//超时时间
private int kVolleyMaxRetryNum =2;//超时重试时间
private Priority mPriority = Request.Priority.NORMAL;//设置优先级
可以通过构造函数来设置响应的值,也可以设置set方法
public MyVolleyRequest(int method, String url, Response.ErrorListener listener) {
super(method, url, listener);
}
//get请求
public MyVolleyRequest(String url, VolleyResponseListener listener,Request.Priority priority,String tag) {
this(Method.GET, url, listener.getmErrorListener());
this.listener = listener;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
if(priority!=null){
this.mPriority =priority;
}
}
//post请求
public MyVolleyRequest(String url, Map<String, String> header,Map<String, String> params, VolleyResponseListener listener,Request.Priority priority,String tag) {
this(Method.POST, url, listener.getmErrorListener());
this.listener = listener;
this.header = header;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
this.params = params;
if(priority!=null){
this.mPriority =priority;
}
setTagAndRetryPolicy(tag,kVolleyTimeOutMS,kVolleyMaxRetryNum);
}
//上传图片
public MyVolleyRequest(String url, Map<String, String> header, VolleyResponseListener listener, Map<String, String> params, List<File> files, String fileName,Request.Priority priority,String tag) {
super(Method.POST, url, listener.getmErrorListener());
this.listener = listener;
this.header = header;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
this.params = params;
this.files = files;
this.fileName = fileName;
entity= new MultipartEntity();
bodyContentType =entity.getContentType().getValue();
buildMultipartEntity();
if(priority!=null){
this.mPriority =priority;
}
}
// 编辑上传文件和参数的加到entity中
private void buildMultipartEntity() {
try {
if (files != null && files.size() > 0) {
for (File f : files) {
//这里要是直接new FileBody(f),默认的content-type是application/octet-stream
FileBody fileBody = new FileBody(f,"image/jpeg");
entity.addPart(fileName, fileBody);
}
long fileLength = entity.getContentLength();
Log.i("Volley_qy", "上传文件的数目是:" + files.size() + ",上传文件的长度是: " + fileLength + " byte");
}
if (params != null && params.size() > 0) {
for (Map.Entry<String, String> entry : params.entrySet()) {
Log.i("Volley_qy", "上传文件的参数是:(" + entry.getKey() + ":" + entry.getValue() + ")");
entity.addPart(entry.getKey(), new StringBody(entry.getValue()));
}
}
} catch (UnsupportedEncodingException e) {
VolleyLog.e("UnsupportedEncodingException");
}
}
之后看看其他的方法
1.parseNetworkResponse
//这里就直接按照StringJson中的解析方式来了
@Override
protected Response<String> parseNetworkResponse(NetworkResponse networkResponse) {
String parsed;
try {
parsed = new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers));
} catch (UnsupportedEncodingException var4) {
parsed = new String(networkResponse.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(networkResponse));
}
2.deliverResponse
//请求接口成功
protected void deliverResponse(String s) {
Log.i("Volley_qy","请求成功返回的数据是:"+s);
mListener.onResponse(s);
}
3.getParams和geBody
//post请求,getparams一般不会调用,如果Request直接接触JsonRequest就会直接走getbody。但是你看源码就会发现,getbody中也会调用getParams()
@Override
public Map<String, String> getParams() {
return params;
}
@Override
public byte[] getBody() throws AuthFailureError {
if(entity!=null){
//文件上传
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
entity.writeTo(bos);
return bos.toByteArray();
} catch (IOException e) {
if(mErrorListener!=null){
mErrorListener.onErrorResponse(new ParseError());
}
Log.e("Volley_qy","============IOException writing to ByteArrayOutputStream");
}
}
return super.getBody();
}
3.getHeaders
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.emptyMap())) {
if (header != null && !header.equals(Collections.emptyMap())) {
headers = header;
} else {
headers = new HashMap<>();
}
}
return headers;
}
4.getContentType
@Override
public String getBodyContentType() {
if (bodyContentType == null || bodyContentType.equals("")) {
bodyContentType = super.getBodyContentType();
}
return bodyContentType;
}
5.设置 优先级
@Override
public Priority getPriority() {
return mPriority;
}
下面看一下具体的使用
Volley使用3步骤
1.创建请求队列
2.创建request
3.将请求添加到队列里
创建请求队列
public class VolleyApplication extends Application {
public static RequestQueue mLocalRequestQueue=null;
public static Context context;
@Override
public void onCreate() {
super.onCreate();
context =this;
}
public static RequestQueue getmLocalRequestQueue() {
if(mLocalRequestQueue ==null){
synchronized (RequestQueue.class){
if(mLocalRequestQueue == null){
mLocalRequestQueue = Volley.newRequestQueue(context);
}
}
}
return mLocalRequestQueue;
}
}
//然后在清单文件中添加这个application,还有请求网络的权限
创建request
MyVolleyRequest request =new MyVolleyRequest(MyAPI.getTest,new VolleyResponseListener(){
@Override
public void onSuccessLoad(String string) {
mDialog.dismiss();
Log.i("TTT", "获取数据成功---1:" + string);
}
@Override
public void onFailedLoad(VolleyError error) {
Log.i("TTT", "获取数据失败---1:" );
mDialog.dismiss();
}
}, Request.Priority.NORMAL,"get1");
MyVolleyRequest request2 =new MyVolleyRequest(MyAPI.getTest,new VolleyResponseListener(){
@Override
public void onSuccessLoad(String string) {
mDialog.dismiss();
Log.i("TTT", "获取数据成功---2:" + string);
}
@Override
public void onFailedLoad(VolleyError error) {
Log.i("TTT", "获取数据失败---2:" );
mDialog.dismiss();
}
}, Request.Priority.HIGH,"get2");
添加到请求队列
VolleyApplication.getmLocalRequestQueue().add(request);
VolleyApplication.getmLocalRequestQueue().add(request2);
输出成功
- 获取数据成功—2:{“code”:”200”,”msg”:”获取数据成功”,”data”:[]}
获取数据成功—1:{“Data”:[{“CouponNumber”:”HYFB4GNN9U”,”CreateDate”:”2017-05-23”,”Status”:”3”}],”ErrorCode”:”200”,”ErrorMsg”:”“,”Status”:”success”}
Post请求测试
MyVolleyRequest postRequest = new MyVolleyRequest(MyAPI.uploadImg, null, params, new VolleyResponseListener() {
@Override
public void onSuccessLoad(String string) {
mDialog.dismiss();
Log.i("yqy", "post获取数据" + string);
volleyRequestContent.setText(string);
}
@Override
public void onFailedLoad(VolleyError error) {
msg.obj = "请求服务器失败";
mDialog.dismiss();
handler.sendMessage(msg);
}
},null, "post");
VolleyApplication.getmLocalRequestQueue().add(postRequest);
输出结果: I/yqy: post获取数据{“Status”:”success”,”ErrorCode”:”200”,”ErrorMsg”:”未取到图片”,”Data”:”“}
图片上传
Map<String, String> params = new HashMap<>();
params.put("warId", "BV67HGP4GS");
params.put("tireId", "3009971551");
params.put("k2name", "s06600008ls");
List<File> files = new ArrayList<>();
String fileName=BitmapCompressUtils.compressImage(photoUri.getPath(),30);
File f = new File(fileName);
if (f != null) {
Log.i("yqy", "文件名称" + f.getName());
files.add(f);
}
MyVolleyRequest uploadRequest = new MyVolleyRequest(MyAPI.uploadImg, null, new VolleyResponseListener() {
@Override
public void onSuccessLoad(String string) {
mDialog.dismiss();
Log.i("yqy", "上传图片成功:" + string);
}
@Override
public void onFailedLoad(VolleyError error) {
mDialog.dismiss();
Log.i("yqy", "请求失败"+error.getMessage());
}
}, params, files, "s06600008ls", null,"upload");
VolleyApplication.getmLocalRequestQueue().add(uploadRequest);
请求返回:
I/yqy: 上传图片成功:{“Status”:”success”,”ErrorCode”:”200”,”ErrorMsg”:”上传成功”,”Data”:”“}
最后,完整的一个Request
public class MyVolleyRequest extends Request<String> {
private MultipartEntity entity ;//一些带有关文件参数和读取的类
private Map<String, String> header;//请求头信息
private VolleyResponseListener listener;
private Response.Listener<String> mListener;//请求成功的监听
private Response.ErrorListener mErrorListener;//请求错误的监听
private String bodyContentType;//文件类型
private Map<String, String> params;
private List<File> files;
private String fileName;//文件组相关的参数名称
private int kVolleyTimeOutMS=20*1000;//超时时间
private int kVolleyMaxRetryNum =2;//超时重试时间
private Priority mPriority =Priority.NORMAL ;//设置优先级
public MyVolleyRequest(int method, String url, Response.ErrorListener listener) {
super(method, url, listener);
}
public MyVolleyRequest(String url, VolleyResponseListener listener,Request.Priority priority,String tag) {
this(Method.GET, url, listener.getmErrorListener());
this.listener = listener;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
if(priority!=null){
mPriority =priority;
}
setTagAndRetryPolicy(tag,kVolleyTimeOutMS,kVolleyMaxRetryNum);
}
public MyVolleyRequest(String url, Map<String, String> header,Map<String, String> params, VolleyResponseListener listener,Request.Priority priority,String tag) {
this(Method.POST, url, listener.getmErrorListener());
this.listener = listener;
this.header = header;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
this.params = params;
if(priority!=null){
this.mPriority =priority;
}
setTagAndRetryPolicy(tag,kVolleyTimeOutMS,kVolleyMaxRetryNum);
}
//上传图片
public MyVolleyRequest(String url, Map<String, String> header, VolleyResponseListener listener, Map<String, String> params, List<File> files, String fileName,Request.Priority priority,String tag) {
super(Method.POST, url, listener.getmErrorListener());
this.listener = listener;
this.header = header;
mListener = listener.getmListener();
mErrorListener = listener.getmErrorListener();
this.params = params;
this.files = files;
this.fileName = fileName;
entity= new MultipartEntity();
bodyContentType =entity.getContentType().getValue();
buildMultipartEntity();
if(priority!=null){
this.mPriority =priority;
}
}
//设置重试和tag
public void setTagAndRetryPolicy(String tag,int timeOut,int maxRetryNum){
setTag(tag);
setRetryPolicy(new DefaultRetryPolicy(timeOut, maxRetryNum, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse networkResponse) {
String parsed;
try {
parsed = new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers));
} catch (UnsupportedEncodingException var4) {
parsed = new String(networkResponse.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(networkResponse));
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.emptyMap())) {
if (header != null && !header.equals(Collections.emptyMap())) {
headers = header;
} else {
headers = new HashMap<>();
}
}
return headers;
}
@Override
public Priority getPriority() {
Log.i("TTT",getTag()+"==="+mPriority);
return mPriority;
}
//post请求,getparams一般不会调用,如果Request直接接触JsonRequest就会直接走getbody。但是你看源码就会发现,getbody中也会调用getParams()
@Override
public Map<String, String> getParams() {
return params;
}
@Override
public byte[] getBody() throws AuthFailureError {
if(entity!=null){
//文件上传
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
entity.writeTo(bos);
return bos.toByteArray();
} catch (IOException e) {
if(mErrorListener!=null){
mErrorListener.onErrorResponse(new ParseError());
}
Log.e("Volley_qy","============IOException writing to ByteArrayOutputStream");
}
}
return super.getBody();
}
@Override
public String getBodyContentType() {
if (bodyContentType == null || bodyContentType.equals("")) {
bodyContentType = super.getBodyContentType();
}
return bodyContentType;
}
@Override
protected void deliverResponse(String s) {
Log.i("Volley_qy",getPriority()+"请求成功返回的数据是:"+s);
mListener.onResponse(s);
}
// 编辑上传文件和参数的加到entity中
private void buildMultipartEntity() {
try {
if (files != null && files.size() > 0) {
for (File f : files) {
FileBody fileBody = new FileBody(f,"image/jpeg");
entity.addPart(fileName, fileBody);
}
long fileLength = entity.getContentLength();
Log.i("Volley_qy", "上传文件的数目是:" + files.size() + ",上传文件的长度是: " + fileLength + " byte");
}
if (params != null && params.size() > 0) {
for (Map.Entry<String, String> entry : params.entrySet()) {
Log.i("Volley_qy", "上传文件的参数是:(" + entry.getKey() + ":" + entry.getValue() + ")");
entity.addPart(entry.getKey(), new StringBody(entry.getValue()));
}
}
} catch (UnsupportedEncodingException e) {
VolleyLog.e("UnsupportedEncodingException");
}
}
}
以上,不对的地方请指出谢谢。