Volley自定义一个Request

之前通过源码简单的了解一下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");
        }

    }
}

以上,不对的地方请指出谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值