美文网首页
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