android开发——okhttp的使用(封装为工具类)

使用功能强大,可以传参(包括json)、传header信息,Cookie的处理,回调函数处理等。先看下调用的代码:

private static final String CONTENT_TYPE = "application/json; charset=utf-8";
public static void login() {
    HashMap<String, String> headerMap = new HashMap<>();
    HashMap<String, String> paramsMap = new HashMap<>();
    headerMap.put("Content-Type", CONTENT_TYPE);//头部信息
    paramsMap.put("userName", USER_NAME);//参数
    paramsMap.put("password", PASSWORD);
    OkhttpUtil.okHttpPost(loginUrl, paramsMap, headerMap, new CallBackUtil.CallBackDefault() {//回调
        @Override
        public void onFailure(Call call, Exception e) {
            LogUtil.e(TAG, e.getMessage());
            TVAppUtil.showToast("网络异常!请确认是否联网,以及服务器地址是否正确!");
            SharedPreferencesUtil.sharePut("newServerAddress","");
        }

        @Override
        public void onResponse(Response response) {
            try {
                isLogin = true;
                Headers responseHeaders = response.headers();
                String c = responseHeaders.get("Set-Cookie");//cookie的处理
                TVAppUtil.setCookie(c);
                updateReportData();
                HandlerUtil.sendTimingRequest();
            } catch (Exception e) {
                LogUtil.e(TAG, e.getMessage());
                TVAppUtil.showToast("登录异常!");
            } finally {
                try {
                    response.body().close();
                } catch (Exception e) {
                }
            }
        }
    });
}

如果参数是json,则调用:

OkhttpUtil.okHttpPostJson(queryWorkerUrl, jsonStr, headerMap, new CallBackUtil.CallBackString() { 
    @Override
    public void onFailure(Call call, Exception e) {
    }
    @Override
    public void onResponse(String response) {
    }
});

使用的步骤如下:

1、配置gradle

compile 'com.squareup.okhttp3:okhttp:3.2.0'

2、准备好这三个搭配使用的工具类(从别的博客获得的,不知来源了,如有侵权还请告知!):

OkhttpUtil、CallBackUtil<T>、RequestUtil

3、代码如下

package com.sinotcc.www.zhonghuakaoqintv.util;

import java.io.File;
import java.util.List;
import java.util.Map;


public class OkhttpUtil {


    public static final String METHOD_GET = "GET";

    public static final String METHOD_POST = "POST";

    public static final String METHOD_PUT = "PUT";

    public static final String METHOD_DELETE = "DELETE";


    public static final String FILE_TYPE_FILE = "file/*";

    public static final String FILE_TYPE_IMAGE = "image/*";

    public static final String FILE_TYPE_AUDIO = "audio/*";

    public static final String FILE_TYPE_VIDEO = "video/*";


    /**
     * get请求
     *
     * @param url:url
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpGet(String url, CallBackUtil callBack) {

        okHttpGet(url, null, null, callBack);

    }


    /**
     * get请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpGet(String url, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpGet(url, paramsMap, null, callBack);

    }


    /**
     * get请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpGet(String url, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_GET, url, paramsMap, headerMap, callBack).execute();

    }


    /**
     * post请求
     *
     * @param url:url
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPost(String url, CallBackUtil callBack) {

        okHttpPost(url, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPost(String url, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpPost(url, paramsMap, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPost(String url, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_POST, url, paramsMap, headerMap, callBack).execute();

    }

    /**
     * post请求
     *
     * @param url:url
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPut(String url, CallBackUtil callBack) {

        okHttpPut(url, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPut(String url, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpPut(url, paramsMap, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPut(String url, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_PUT, url, paramsMap, headerMap, callBack).execute();

    }

    /**
     * post请求
     *
     * @param url:url
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpDelete(String url, CallBackUtil callBack) {

        okHttpDelete(url, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpDelete(String url, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpDelete(url, paramsMap, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpDelete(String url, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_DELETE, url, paramsMap, headerMap, callBack).execute();

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param jsonStr:json格式的键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPostJson(String url, String jsonStr, CallBackUtil callBack) {

        okHttpPostJson(url, jsonStr, null, callBack);

    }


    /**
     * post请求,可以传递参数
     *
     * @param url:url
     * @param jsonStr:json格式的键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpPostJson(String url, String jsonStr, Map<String, String> headerMap, CallBackUtil callBack) {
        new RequestUtil(METHOD_POST, url, jsonStr, headerMap, callBack).execute();
    }


    /**
     * post请求,上传单个文件
     *
     * @param url:url
     * @param file:File对象
     * @param fileKey:上传参数时file对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
     */

    public static void okHttpUploadFile(String url, File file, String fileKey, String fileType, CallBackUtil callBack) {

        okHttpUploadFile(url, file, fileKey, fileType, null, callBack);

    }


    /**
     * post请求,上传单个文件
     *
     * @param url:url
     * @param file:File对象
     * @param fileKey:上传参数时file对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
     */

    public static void okHttpUploadFile(String url, File file, String fileKey, String fileType, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpUploadFile(url, file, fileKey, fileType, paramsMap, null, callBack);

    }


    /**
     * post请求,上传单个文件
     *
     * @param url:url
     * @param file:File对象
     * @param fileKey:上传参数时file对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
     */

    public static void okHttpUploadFile(String url, File file, String fileKey, String fileType, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_POST, url, paramsMap, file, fileKey, fileType, headerMap, callBack).execute();

    }


    /**
     * post请求,上传多个文件,以list集合的形式
     *
     * @param url:url
     * @param fileList:集合元素是File对象
     * @param fileKey:上传参数时fileList对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadListFile(String url, List<File> fileList, String fileKey, String fileType, CallBackUtil callBack) {

        okHttpUploadListFile(url, null, fileList, fileKey, fileType, callBack);

    }


    /**
     * post请求,上传多个文件,以list集合的形式
     *
     * @param url:url
     * @param fileList:集合元素是File对象
     * @param fileKey:上传参数时fileList对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadListFile(String url, Map<String, String> paramsMap, List<File> fileList, String fileKey, String fileType, CallBackUtil callBack) {

        okHttpUploadListFile(url, paramsMap, fileList, fileKey, fileType, null, callBack);

    }


    /**
     * post请求,上传多个文件,以list集合的形式
     *
     * @param url:url
     * @param fileList:集合元素是File对象
     * @param fileKey:上传参数时fileList对应的键
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadListFile(String url, Map<String, String> paramsMap, List<File> fileList, String fileKey, String fileType, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_POST, url, paramsMap, fileList, fileKey, fileType, headerMap, callBack).execute();

    }


    /**
     * post请求,上传多个文件,以map集合的形式
     *
     * @param url:url
     * @param fileMap:集合key是File对象对应的键,集合value是File对象
     * @param fileType:File类型,是image,video,audio,file
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadMapFile(String url, Map<String, File> fileMap, String fileType, CallBackUtil callBack) {

        okHttpUploadMapFile(url, fileMap, fileType, null, callBack);

    }


    /**
     * post请求,上传多个文件,以map集合的形式
     *
     * @param url:url
     * @param fileMap:集合key是File对象对应的键,集合value是File对象
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadMapFile(String url, Map<String, File> fileMap, String fileType, Map<String, String> paramsMap, CallBackUtil callBack) {

        okHttpUploadMapFile(url, fileMap, fileType, paramsMap, null, callBack);

    }


    /**
     * post请求,上传多个文件,以map集合的形式
     *
     * @param url:url
     * @param fileMap:集合key是File对象对应的键,集合value是File对象
     * @param fileType:File类型,是image,video,audio,file
     * @param paramsMap:map集合,封装键值对参数
     * @param headerMap:map集合,封装请求头键值对
     * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
     */

    public static void okHttpUploadMapFile(String url, Map<String, File> fileMap, String fileType, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        new RequestUtil(METHOD_POST, url, paramsMap, fileMap, fileType, headerMap, callBack).execute();

    }


    /**
     * 下载文件,不带参数
     */

    public static void okHttpDownloadFile(String url, CallBackUtil.CallBackFile callBack) {

        okHttpDownloadFile(url, null, callBack);

    }


    /**
     * 下载文件,带参数
     */

    public static void okHttpDownloadFile(String url, Map<String, String> paramsMap, CallBackUtil.CallBackFile callBack) {

        okHttpGet(url, paramsMap, null, callBack);

    }

    /**
     * 加载图片
     */

    public static void okHttpGetBitmap(String url, CallBackUtil.CallBackBitmap callBack) {

        okHttpGetBitmap(url, null, callBack);

    }

    /**
     * 加载图片,带参数
     */

    public static void okHttpGetBitmap(String url, Map<String, String> paramsMap, CallBackUtil.CallBackBitmap callBack) {

        okHttpGet(url, paramsMap, null, callBack);

    }


}
package com.sinotcc.www.zhonghuakaoqintv.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Response;


public abstract class CallBackUtil<T> {
    public static Handler mMainHandler = new Handler(Looper.getMainLooper());
    public  void onProgress(float progress, long total ){};
    public  void onError(final Call call, final Exception e){
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                onFailure(call,e);
            }
        });
    };

    public  void onSeccess(Call call, Response response){
        final T obj = onParseResponse(call, response);
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                onResponse(obj);
            }
        });
    };

    /**
     * 解析response,执行在子线程
     */
    public abstract T onParseResponse(Call call, Response response);
    /**
     * 访问网络失败后被调用,执行在UI线程
     */
    public abstract void onFailure(Call call, Exception e);
    /**
     *
     * 访问网络成功后被调用,执行在UI线程
     */
    public abstract void onResponse(T response);
    public static abstract class CallBackDefault extends CallBackUtil<Response>{
        @Override
        public Response onParseResponse(Call call, Response response) {
            return response;
        }
    }
    public static abstract class CallBackString extends CallBackUtil<String>{
        @Override
        public String onParseResponse(Call call, Response response) {
            try {
                return response.body().string();
            } catch (IOException e) {
                new RuntimeException("failure");
                return "";
            }
        }
    }

    public static abstract class CallBackBitmap extends CallBackUtil<Bitmap>{
        private int mTargetWidth;
        private int mTargetHeight;
        public CallBackBitmap(){};
        public CallBackBitmap(int targetWidth,int targetHeight){
            mTargetWidth = targetWidth;
            mTargetHeight = targetHeight;
        };
        public CallBackBitmap(ImageView imageView){
            int width = imageView.getWidth();
            int height = imageView.getHeight();
            if(width <=0 || height <=0){
                throw new RuntimeException("无法获取ImageView的width或height");
            }
            mTargetWidth = width;
            mTargetHeight = height;
        };
        @Override
        public Bitmap onParseResponse(Call call, Response response) {
            if(mTargetWidth ==0 || mTargetHeight == 0){
                return BitmapFactory.decodeStream(response.body().byteStream());
            }else {
                return getZoomBitmap(response);
            }
        }

        /**
         * 压缩图片,避免OOM异常
         */
        private Bitmap getZoomBitmap(Response response) {
            byte[] data = null;
            try {
                data = response.body().bytes();
            } catch (IOException e) {
                e.printStackTrace();
            }
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(data,0,data.length,options);
            int picWidth = options.outWidth;
            int picHeight = options.outHeight;
            int sampleSize = 1;
            int heightRatio = (int) Math.floor((float) picWidth / (float) mTargetWidth);
            int widthRatio = (int) Math.floor((float) picHeight / (float) mTargetHeight);
            if (heightRatio > 1 || widthRatio > 1){
                sampleSize = Math.max(heightRatio,widthRatio);
            }
            options.inSampleSize = sampleSize;
            options.inJustDecodeBounds = false;
            Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length,options);
            if(bitmap == null){
                throw new RuntimeException("Failed to decode stream.");
            }
            return bitmap;
        }
    }

    /**
     * 下载文件时的回调类
     */
    public static abstract class CallBackFile extends CallBackUtil<File>{
        private final String mDestFileDir;
        private final String mdestFileName;
        /**
         *
         * @param destFileDir:文件目录
         * @param destFileName:文件名
         */
        public CallBackFile(String destFileDir, String destFileName){
            mDestFileDir = destFileDir;
            mdestFileName = destFileName;
        }
        @Override
        public File onParseResponse(Call call, Response response) {
            InputStream is = null;
            byte[] buf = new byte[1024*8];
            int len = 0;
            FileOutputStream fos = null;
            try{
                is = response.body().byteStream();
                final long total = response.body().contentLength();
                long sum = 0;
                File dir = new File(mDestFileDir);
                if (!dir.exists()){
                    dir.mkdirs();
                }
                File file = new File(dir, mdestFileName);
                fos = new FileOutputStream(file);
                while ((len = is.read(buf)) != -1){
                    sum += len;
                    fos.write(buf, 0, len);
                    final long finalSum = sum;
                    mMainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            onProgress(finalSum * 100.0f / total,total);
                        }
                    });
                }
                fos.flush();
                return file;
            } catch (Exception e) {
                e.printStackTrace();
            } finally{
                try{
                    response.body().close();
                    if (is != null) is.close();
                } catch (IOException e){
                }
                try{
                    if (fos != null) fos.close();
                } catch (IOException e){

                }
            }
            return null;
        }
    }
}
package com.sinotcc.www.zhonghuakaoqintv.util;

import android.text.TextUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;


class RequestUtil {

    private String mMetyodType;//请求方式,目前只支持get和post

    private String mUrl;//接口

    private Map<String, String> mParamsMap;//键值对类型的参数,只有这一种情况下区分post和get。

    private String mJsonStr;//json类型的参数,post方式

    private File mFile;//文件的参数,post方式,只有一个文件

    private List<File> mfileList;//文件集合,这个集合对应一个key,即mfileKey

    private String mfileKey;//上传服务器的文件对应的key

    private Map<String, File> mfileMap;//文件集合,每个文件对应一个key

    private String mFileType;//文件类型的参数,与file同时存在

    private Map<String, String> mHeaderMap;//头参数

    private CallBackUtil mCallBack;//回调接口

    private OkHttpClient mOkHttpClient;//OKhttpClient对象

    private Request mOkHttpRequest;//请求对象

    private Request.Builder mRequestBuilder;//请求对象的构建者

    RequestUtil(String methodType, String url, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        this(methodType, url, null, null, null, null, null, null, paramsMap, headerMap, callBack);

    }

    RequestUtil(String methodType, String url, String jsonStr, Map<String, String> headerMap, CallBackUtil callBack) {

        this(methodType, url, jsonStr, null, null, null, null, null, null, headerMap, callBack);

    }

    RequestUtil(String methodType, String url, Map<String, String> paramsMap, File file, String fileKey, String fileType, Map<String, String> headerMap, CallBackUtil callBack) {

        this(methodType, url, null, file, null, fileKey, null, fileType, paramsMap, headerMap, callBack);

    }

    RequestUtil(String methodType, String url, Map<String, String> paramsMap, List<File> fileList, String fileKey, String fileType, Map<String, String> headerMap, CallBackUtil callBack) {

        this(methodType, url, null, null, fileList, fileKey, null, fileType, paramsMap, headerMap, callBack);

    }

    RequestUtil(String methodType, String url, Map<String, String> paramsMap, Map<String, File> fileMap, String fileType, Map<String, String> headerMap, CallBackUtil callBack) {

        this(methodType, url, null, null, null, null, fileMap, fileType, paramsMap, headerMap, callBack);

    }

    private RequestUtil(String methodType, String url, String jsonStr, File file, List<File> fileList, String fileKey, Map<String, File> fileMap, String fileType, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {

        mMetyodType = methodType;

        mUrl = url;

        mJsonStr = jsonStr;

        mFile = file;

        mfileList = fileList;

        mfileKey = fileKey;

        mfileMap = fileMap;

        mFileType = fileType;

        mParamsMap = paramsMap;

        mHeaderMap = headerMap;

        mCallBack = callBack;

        getInstance();

    }

    /**
     * 创建OKhttpClient实例。
     */

    private void getInstance() {

        mOkHttpClient = new OkHttpClient();

        mRequestBuilder = new Request.Builder();

        if (mFile != null || mfileList != null || mfileMap != null) {//先判断是否有文件,

            setFile();

        } else {

            //设置参数

            switch (mMetyodType) {

                case OkhttpUtil.METHOD_GET:

                    setGetParams();

                    break;

                case OkhttpUtil.METHOD_POST:

                    mRequestBuilder.post(getRequestBody());

                    break;

                case OkhttpUtil.METHOD_PUT:

                    mRequestBuilder.put(getRequestBody());

                    break;

                case OkhttpUtil.METHOD_DELETE:

                    mRequestBuilder.delete(getRequestBody());

                    break;

            }

        }

        mRequestBuilder.url(mUrl);

        if (mHeaderMap != null) {

            setHeader();

        }

        //mRequestBuilder.addHeader("Authorization","Bearer "+"token");可以把token添加到这儿

        mOkHttpRequest = mRequestBuilder.build();

    }

    /**
     * 得到body对象
     */

    private RequestBody getRequestBody() {

        /**

         * 首先判断mJsonStr是否为空,由于mJsonStr与mParamsMap不可能同时存在,所以先判断mJsonStr

         */

        if (!TextUtils.isEmpty(mJsonStr)) {

            MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,

            return RequestBody.create(JSON, mJsonStr);//json数据,

        }

        /**

         * post,put,delete都需要body,但也都有body等于空的情况,此时也应该有body对象,但body中的内容为空

         */

        FormBody.Builder formBody = new FormBody.Builder();

        if (mParamsMap != null) {

            for (String key : mParamsMap.keySet()) {

                formBody.add(key, mParamsMap.get(key));

            }

        }

        return formBody.build();

    }

    /**
     * get请求,只有键值对参数
     */

    private void setGetParams() {

        if (mParamsMap != null) {

            mUrl = mUrl + "?";

            for (String key : mParamsMap.keySet()) {

                mUrl = mUrl + key + "=" + mParamsMap.get(key) + "&";

            }

            mUrl = mUrl.substring(0, mUrl.length() - 1);

        }

    }

    /**
     * 设置上传文件
     */

    private void setFile() {

        if (mFile != null) {//只有一个文件,且没有文件名

            if (mParamsMap == null) {

                setPostFile();

            } else {

                setPostParameAndFile();

            }

        } else if (mfileList != null) {//文件集合,只有一个文件名。所以这个也支持单个有文件名的文件

            setPostParameAndListFile();

        } else if (mfileMap != null) {//多个文件,每个文件对应一个文件名

            setPostParameAndMapFile();

        }

    }

    /**
     * 只有一个文件,且提交服务器时不用指定键,没有参数
     */

    private void setPostFile() {

        if (mFile != null && mFile.exists()) {

            MediaType fileType = MediaType.parse(mFileType);

            RequestBody body = RequestBody.create(fileType, mFile);//json数据,

            mRequestBuilder.post(new ProgressRequestBody(body, mCallBack));

        }

    }

    /**
     * 只有一个文件,且提交服务器时不用指定键,带键值对参数
     */

    private void setPostParameAndFile() {

        if (mParamsMap != null && mFile != null) {

            MultipartBody.Builder builder = new MultipartBody.Builder();

            builder.setType(MultipartBody.FORM);

            for (String key : mParamsMap.keySet()) {

                builder.addFormDataPart(key, mParamsMap.get(key));

            }

            builder.addFormDataPart(mfileKey, mFile.getName(), RequestBody.create(MediaType.parse(mFileType), mFile));

            mRequestBuilder.post(new ProgressRequestBody(builder.build(), mCallBack));

        }

    }

    /**
     * 文件集合,可能带有键值对参数
     */

    private void setPostParameAndListFile() {

        if (mfileList != null) {

            MultipartBody.Builder builder = new MultipartBody.Builder();

            builder.setType(MultipartBody.FORM);

            if (mParamsMap != null) {

                for (String key : mParamsMap.keySet()) {

                    builder.addFormDataPart(key, mParamsMap.get(key));

                }

            }

            for (File f : mfileList) {

                builder.addFormDataPart(mfileKey, f.getName(), RequestBody.create(MediaType.parse(mFileType), f));

            }

            mRequestBuilder.post(builder.build());

        }

    }

    /**
     * 文件Map,可能带有键值对参数
     */

    private void setPostParameAndMapFile() {

        if (mfileMap != null) {

            MultipartBody.Builder builder = new MultipartBody.Builder();

            builder.setType(MultipartBody.FORM);

            if (mParamsMap != null) {

                for (String key : mParamsMap.keySet()) {

                    builder.addFormDataPart(key, mParamsMap.get(key));

                }

            }

            for (String key : mfileMap.keySet()) {

                builder.addFormDataPart(key, mfileMap.get(key).getName(), RequestBody.create(MediaType.parse(mFileType), mfileMap.get(key)));

            }

            mRequestBuilder.post(builder.build());

        }

    }

    /**
     * 设置头参数
     */

    private void setHeader() {

        if (mHeaderMap != null) {

            for (String key : mHeaderMap.keySet()) {

                mRequestBuilder.addHeader(key, mHeaderMap.get(key));

            }

        }

    }

    void execute() {

        mOkHttpClient.newCall(mOkHttpRequest).enqueue(new Callback() {

            @Override
            public void onFailure(final Call call, final IOException e) {
                if (mCallBack != null) {
                    mCallBack.onError(call, e);
                }
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                if (mCallBack != null) {
                    mCallBack.onSeccess(call, response);
                }
            }
        });

    }

    /**
     * 自定义RequestBody类,得到文件上传的进度
     */

    private static class ProgressRequestBody extends RequestBody {

        //实际的待包装请求体

        private final RequestBody requestBody;

        //包装完成的BufferedSink

        private BufferedSink bufferedSink;

        private CallBackUtil callBack;

        ProgressRequestBody(RequestBody requestBody, CallBackUtil callBack) {

            this.requestBody = requestBody;

            this.callBack = callBack;

        }

        /**
         * 重写调用实际的响应体的contentType
         */

        @Override

        public MediaType contentType() {

            return requestBody.contentType();

        }

        /**
         * 重写调用实际的响应体的contentLength ,这个是文件的总字节数
         */

        @Override

        public long contentLength() throws IOException {

            return requestBody.contentLength();

        }

        /**
         * 重写进行写入
         */

        @Override

        public void writeTo(BufferedSink sink) throws IOException {

            if (bufferedSink == null) {

                bufferedSink = Okio.buffer(sink(sink));

            }

            requestBody.writeTo(bufferedSink);

            //必须调用flush,否则最后一部分数据可能不会被写入

            bufferedSink.flush();

        }

        /**
         * 写入,回调进度接口
         */

        private Sink sink(BufferedSink sink) {

            return new ForwardingSink(sink) {

                //当前写入字节数

                long bytesWritten = 0L;

                //总字节长度,避免多次调用contentLength()方法

                long contentLength = 0L;

                @Override

                public void write(Buffer source, long byteCount) throws IOException {

                    super.write(source, byteCount);//这个方法会循环调用,byteCount是每次调用上传的字节数。

                    if (contentLength == 0) {

                        //获得总字节长度

                        contentLength = contentLength();

                    }

                    //增加当前写入的字节数

                    bytesWritten += byteCount;

                    final float progress = bytesWritten * 1.0f / contentLength;

                    CallBackUtil.mMainHandler.post(new Runnable() {

                        @Override

                        public void run() {

                            callBack.onProgress(progress, contentLength);

                        }

                    });

                }

            };

        }

    }

}

猜你喜欢

转载自blog.csdn.net/river66/article/details/86570757
今日推荐