美文网首页
OkHttp简单使用封装

OkHttp简单使用封装

作者: 橘子树上结西瓜 | 来源:发表于2018-01-23 15:55 被阅读14次
//OkHttp请求封装工具类
public class OkHttpManager {

    private OkHttpClient okHttpClient;
    private Handler mHandler;
    private volatile static OkHttpManager manager;//防止多个线程访问该工具类,发生并发修改异常

    private OkHttpManager() {
        okHttpClient = new OkHttpClient();
        mHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 获取OkHttpManager单一实例
     * 注:
     * 1.synchronized关键字用于多线程访问程序中的共享资源时实现顺序同步访问资源
     * 2.synchronized关键字修饰代码块---同步代码块;
     * 同一时间段,只能被同一线程调用,其他线程只能等待。【防止并发修改异常】
     */
    public static OkHttpManager getInstance() {
        OkHttpManager instance = null;
        if (manager == null) {
            synchronized (OkHttpManager.class) {
                if (instance == null) {
                    instance = new OkHttpManager();
                    manager = instance;
                }
            }
        }
        return instance;
    }

    /**
     * 异步Get请求
     *
     * @param url
     * @param callBackJsonResult
     */
    public void sendGet(String url, final CallBackJsonResult callBackJsonResult) {
        final Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {//注:同步请求:execute();异步请求:enqueue(new Callback())
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();//打印异常
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onSuccessJsonStringMethod(response.body().string(), callBackJsonResult);
                }
            }
        });
    }

    /**
     * 模拟表单Post提交
     *
     * @param url      地址
     * @param params   请求参数
     * @param callBack 请求成功回调
     */
    public void sendPost(String url, Map<String, String> params, final CallBackJSONObjectResult callBack) {
        //创建Form表单对象,add多个键值队
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                formBodyBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        RequestBody requestBody = formBodyBuilder.build();//From表单对象

        //创建一个Request请求,发起异步网络请求
        Request request = new Request.Builder().url(url).post(requestBody).build();//post请求
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onSuccessJsonObjectMethod(response.body().string(), callBack);
                }
            }
        });
    }


    /**
     * post请求上传文件和参数
     * @param url
     * @param map
     * @param fileList
     * @param callBack
     */
    public void postFileAndParams(final String url, final Map<String, Object> map, List<File> fileList,final CallBackJSONObjectResult callBack) {
        //1.form表单形式上传(分块上传)
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
        multipartBodyBuilder.setType(MultipartBody.FORM);//设置为表单类型
        for (File file : fileList) {//文件
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);//添加多个文件
            multipartBodyBuilder.addFormDataPart("files", file.getName(), fileBody);//files-文件对应的键名
        }
        if (map != null) {//普通参数[添加表单键值]
            for (Map.Entry entry : map.entrySet()) {
                multipartBodyBuilder.addFormDataPart(valueOf(entry.getKey()), valueOf(entry.getValue()));
            }
        }
        RequestBody requestBody = multipartBodyBuilder.build();//分块请求对象

        //2.创建一个Request请求,发起异步网络请求,readTimeout("请求超时时间" , 时间单位);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        okHttpClient.newBuilder().readTimeout(6000, TimeUnit.MILLISECONDS).build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onSuccessJsonObjectMethod(response.body().string(), callBack);
                }
            }
        });
    }
    
    /**
     * 小文件下载
     * @param url      下载连接
     * @param saveDir  储存下载文件的SDCard目录
     * @param name     文件名
     * @param listener 下载监听
     */
    public void download(final String url, final String saveDir, final String name, final OnDownloadListener listener) {
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                listener.onDownloadFailed();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                String savePath = isExistDir(saveDir);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File file = new File(savePath, name);
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成
                    listener.onDownloadSuccess();
                } catch (Exception e) {
                    listener.onDownloadFailed();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

    /**
     * @param saveDir
     * @return
     * @throws IOException 判断下载目录是否存在
     */
    private String isExistDir(String saveDir) throws IOException {
        // 下载位置
        File downloadFile = new File(saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }
    
   /**
     * @param url
     * @return 从下载连接中解析出文件名
     */
    @NonNull
    private String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }

    public interface OnDownloadListener {
        /**
         * 下载成功
         */
        void onDownloadSuccess();

        /**
         * @param progress 下载进度
         */
        void onDownloading(int progress);

        /**
         * 下载失败
         */
        void onDownloadFailed();
    }

    /**
     * 请求返回的结果是json字符串
     *
     * @param jsonValue
     * @param callBack
     */
    private void onSuccessJsonStringMethod(final String jsonValue, final CallBackJsonResult callBack) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        callBack.onResponse(jsonValue);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        });
    }

    /**
     * 请求返回的是byte[] 数组
     *
     * @param data
     * @param callBack
     */
    private void onSuccessByteMethod(final byte[] data, final CallBackByteResult callBack) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onResponse(data);
                }
            }
        });
    }

    /**
     * 返回响应的结果是json对象
     *
     * @param jsonValue
     * @param callBack
     */
    private void onSuccessJsonObjectMethod(final String jsonValue, final CallBackJSONObjectResult callBack) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        callBack.onResponse(new JSONObject(jsonValue));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 请求返回的结果是json字符串-回调接口
     */
    public interface CallBackJsonResult {
        void onResponse(String result);
    }

    /**
     * 请求返回的结果是JSONObject对象-回调接口
     */
    public interface CallBackJSONObjectResult {
        void onResponse(JSONObject jsonObject);
    }

    /**
     * 请求返回的结果是byte[]字节数组-回调接口
     */
    public interface CallBackByteResult {
        void onResponse(byte[] result);
    }


    //=====================1.MediaType详解=====================

    /*
    public static final MediaType MEDIA_TYPE_MARKDOWN  = MediaType.parse("text/x-markdown; charset=utf-8");
    属性:
    text/html : HTML格式
    text/plain :纯文本格式
    text/xml :  XML格式
    image/gif :gif图片格式
    image/jpeg :jpg图片格式
    image/png:png图片格式
    以application开头的媒体格式类型:

    application/xhtml+xml :XHTML格式
    application/xml     : XML数据格式
    application/atom+xml  :Atom XML聚合格式
    application/json    : JSON数据格式
    application/pdf       :pdf格式
    application/msword  : Word文档格式
    application/octet-stream : 二进制流数据(如常见的文件下载)
    application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

    另外一种常见的媒体格式是上传文件之时使用的:
    multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
    注意:MediaType.parse("image/png")里的"image/png"不知道该填什么,可以参考---》http://www.w3school.com.cn/media/media_mimeref.asp
    如何使用呢?(在请求体里面写入类型和需要写入的数据,通过post请求)
    String body = "hdsoifhjoihdsfh";
    RequestBody body = RequestBody.create(MEDIA_TYPE_MARKDOWN, body);
    */

    //=====================2.超时设置=====================
    /*OkHttpClient client=new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)       //设置连接超时
            .readTimeout(60, TimeUnit.SECONDS)          //设置读超时
            .writeTimeout(60,TimeUnit.SECONDS)          //设置写超时
            .retryOnConnectionFailure(true)             //是否自动重连
            .build();*/

}

相关文章

网友评论

      本文标题:OkHttp简单使用封装

      本文链接:https://www.haomeiwen.com/subject/kobsaxtx.html