OKHttp使用简单介绍,实用教程

OKHttp使用简单介绍,实用教程

鸿洋大神关于OKHttp教程
OKHttp源码解析

本篇博客主要是讲解一个关于okhttp的实际使用。
所以这里主要是介绍异步请求。

okhttp get请求

如果有参数首先需要拼接访问URL

/**
     * 获取拼接参数
     *
     * @return String 可能为null
     */
    public String spliceParams() {
        if (!params.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            // 拼接参数
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(entry.getKey());
                sb.append("=");
                sb.append(entry.getValue());
                sb.append("&");
            }
            // 删除最后一个多余的 &
            sb = sb.delete(sb.length() - 1,  sb.length());
            return sb.toString();
        }
        return null;
    }

获取完整的访问路径

 /**
     * 获取完整访问路径
     *
     * @param url 地址
     * @return 带参数的完整路径
     */
    public String getCompleteUrl(String url) {
        if (TextUtils.isEmpty(url))
            throw new NullPointerException("url为空");
        String paramsStr = spliceParams();
        if (paramsStr == null) {
            return url;
        }
        return url + "?" + paramsStr;
    }

封装请求

Request.Builder builder;
        builder = new Request.Builder().get().url(url);
        if (tag != null) {
            tags.add(tag);// 添加请求标签到集合
            tagCancelFlags.put(tag, false);
            builder.tag(tag);
        }
okhttp post请求

进行参数封装和请求封装

FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
        if (params != null && params.sizeOfNormal() >= 1) { // 进行非文件参数封装
            for (String key : params.getKeyList()) {
                formEncodingBuilder.add(key, params.getValue(key));
            }
        }
        Request.Builder builder;
        RequestBody body = formEncodingBuilder.build();
        builder = new Request.Builder().post(body).url(url);
        if (tag != null) {
            tags.add(tag); // 添加请求标签到集合
            tagCancelFlags.put(tag, false);
            builder.tag(tag);
        }
okhttp 上传文件

进行参数和请求的封装

MultipartBuilder mulBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
        // 进行非文件参数封装
        if (params.sizeOfNormal() >= 1) {
            for (String key : params.getKeyList()) {
                mulBuilder.addFormDataPart(key, params.getValue(key));
            }
        }
        // 进行文件参数的封装
        if (params.sizeOfFile() >= 1) {
            for (String key : params.getFileKeys()) {
                ArrayList<File> files = params.getFile(key);
                for (File file : files) {
                    // 注意 必须指定 filename 这个参数
                    mulBuilder.addPart(Headers.of("Content-Disposition", "form-data; name=\""
                                    + key + "\"; filename=\"" + file.getName() + "\""),
                            RequestBody.create(MediaType.parse(mediaType), file));
                }
            }
        }
        // 请求体
        RequestBody body = mulBuilder.build();
        Request.Builder builder = new Request.Builder().post(body).url(url);
        if (tag != null) {
            tags.add(tag); // 添加请求标签到集合
            tagCancelFlags.put(tag, false);
            builder.tag(tag);
        }
okhttp 下载文件

这个下载可以通过get或者post,这里主要是介绍数据的解析

/**
     * 从响应流里面读取文件数据
     *
     * @param response  响应
     * @param fileDir   文件目录
     * @param fileName  文件名
     * @param tag       请求标签
     * @param mCallBack 回调
     */
    private void parseFile(Response response, String fileDir, String fileName, Object tag, OKHttpResultCallBack mCallBack) {
        if (response.isSuccessful()) {
            // 读取文件
            InputStream is = null;
            byte[] buffer = new byte[1024];
            int len;
            long currentTotalLen = 0L;
            FileOutputStream fos = null;
            try {
                is = response.body().byteStream();
                File file = new File(fileDir, fileName);
                if (file.exists()) // 如果文件存在 则删除
                    file.delete();
                fos = new FileOutputStream(file);
                while ((len = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                    currentTotalLen += len;
                    sendDownProgressMessage(tag, len, currentTotalLen,
                            response.body().contentLength(), mCallBack);
                }
                fos.flush();
                sendResponseMessage(tag, file.getAbsolutePath(), mCallBack);
            } catch (IOException e) {
                e.printStackTrace();
                sendFailureMessage(tag, e, mCallBack);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (fos != null) {
                            try {
                                fos.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        } else {
            sendFailureMessage(tag, new OKResponseException(), mCallBack);
        }
    }

统一的发起请求的位置

// 得到Call对象 并把该对象添加带调度队列中 等待执行
        /*
        * newCall 会得到一个Call对象
        * Call是一个准备好执行的请求 可以取消 表示单个的请求/响应流 不能执行俩次
        * enqueue 添加带调度队列中 等待执行
        * 通常会立即执行,除非当前有正在执行的请求
        * 接收一个回调 在完成或者异常时调用
        * 如果在回调之前执行cancel操作不会回调 (注意回调在当前线程不在UI线程)
        * */
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                sendFailureMessage(tag, e, mCallBack);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    sendResponseMessage(tag, response.body().string(), mCallBack);
                } else {
                    sendFailureMessage(tag, new OKResponseException(), mCallBack);
                }
            }
        });
okhttp 取消请求
  • 取消单个请求
/**
     * 取消请求
     *
     * @param tag 请求标签
     */
    private void _cancelRequest(Object tag, OnCancelRequestHandler cancelRequestHandler) {
        if (tag == null || !tags.contains(tag)) {
            throw new NullPointerException("tag为空或不存在");
        }
        tagCancelFlags.put(tag, true); // 设置取消标记
        okHttpClient.cancel(tag); // 取消请求
        tags.remove(tag); // 将tag从请求标签集合里面移除
        // 添加一个回调
        if (cancelRequestHandler != null) {
            cancelRequestHandler.onCancle();
        }
    }
  • 取消全部请求
/**
     * 取消全部请求
     */
    private void _cancelAll(OnCancelRequestHandler cancelRequestHandler) {
        if (tags == null || tags.isEmpty()) {
            return;
        }
        for (Object tag : getInstance().tags) {
            okHttpClient.cancel(tag);
            tagCancelFlags.put(tag, true);
        }
        tags.clear();
        if (cancelRequestHandler != null) {
            cancelRequestHandler.onCancle();
        }
    }

关于向自签名的网站发起请求时候,设置安全证书代码
该段代码来自 上面 鸿洋大神的博客

    /**
     * 进行证书验证 访问https
     *
     * @param certificates 文件流
     */
    public void setCertificates(InputStream... certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException ignored) {
                }
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");

            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

            trustManagerFactory.init(keyStore);
            sslContext.init
                    (
                            null,
                            trustManagerFactory.getTrustManagers(),
                            new SecureRandom()
                    );

            okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

完整代码请查看
okhttp-library

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值