当前位置:   article > 正文

你必须学会的okhttp——入门篇_okhttp 2.7

okhttp 2.7

早在毕业那段期间,群里有很多小伙伴在问关于okhttp的问题,当时因为不了解。所以没有回答的上。记得十月份有次面试,一个面试官问我关于网络请求的东西时,我记得当时我是说。我是通过HttpClient封装了一个网络请求的工具类。当然,或许他想问的是我关于okhttp有没有了解把。谷歌在6.0中删除了关于httpclient的API。(其实我有httpclient源码)。于是乎,为了了解下,最近还是学习了下。

简单说下学习okhttp的理由

  1. google在Android 6.0中删除了关于Httpclient的APi,采用的则是okhttp
  2. 高效的使用http,使应用运行更快,更省流量
  3. 响应缓存数据,避免重复网络请求
  4. 无缝的支持GZIP从而来减少流量的使用
  5. 使用简单方便,请求和响应的APi具有流畅的建造和不变性。同时支持同步异步调用回调函数
  6. 如果网络出现问题,他会从常见的连接问题中恢复
  7. 如果服务器配置多个URL,当第一个连接失败时,它会尝试链接下一个

配置环境

github地址:http://github.com/square/okhttp

在build.gradle添加:

compile 'com.squareup.okhttp:okhttp:2.7.5'
compile 'com.squareup.okio:okio:1.11.0'
  • 1
  • 2

jar下载地址:

Okhttp
OKio

基本使用教程

1) OkHttpClient:新建一个OkHttpClient实例,用于处理请求。

2) Request:构建请求参数,如url,请求方式,请求参数,header等。

3) Call:生成一个具体请求实例,相当于将请求封装成了任务;两种方式:

    ①、call.execute(),非异步方式,会阻塞线程,等待返回结果。

    ②、call.enqueue(Callback),异步方式。
  • 1
  • 2
  • 3

4) Response:结果响应

HttpGet

同步http请求
private OkHttpClient okHttpClient = new OkHttpClient();
private Response response;
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(15, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(15, TimeUnit.SECONDS);
Request request = new Request.Builder().url(url).get().build();
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                      Log.i(TAG, " onResponse() reuslt=" + response.body().string());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
异步http请求
private OkHttpClient okHttpClient = new OkHttpClient();
private Response response;
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(15, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(15, TimeUnit.SECONDS);
Request request = new Request.Builder().url(url).get().build();
okHttpClient.newCall(request).enqueue(new Callback() {

    public void onFailure(Call call, IOException e) {
        Log.e(TAG, "onFailure() e=" + e);
    }

    public void onResponse(Call call, final Response response) throws IOException {
        Log.i(TAG, " onResponse() reuslt=" + response.body().string());
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

HttpPost

看了上面的简单的get请求,基本上整个的用法也就掌握了。post和get的用法差不多。

同步的Post请求
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(15, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(15, TimeUnit.SECONDS);
RequestBody body=new FormEncodingBuilder().add("name","马云飞").build();
Request request = new Request.Builder().url(url).post(body).build();
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                     Log.i(TAG, " onResponse() reuslt=" + response.body().string());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
异步的Post请求
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(15, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(15, TimeUnit.SECONDS);
RequestBody body=new FormEncodingBuilder().add("name","马云飞").build();
Request request = new Request.Builder().url(url).post(body).build();
okHttpClient.newCall(request).enqueue(new Callback() {

    public void onFailure(Call call, IOException e) {
        Log.e(TAG, "onFailure() e=" + e);
    }

    public void onResponse(Call call, final Response response) throws IOException {
        Log.i(TAG, " onResponse() reuslt=" + response.body().string());
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

此时,基本的get与post就这么介绍完了。那么用到网络请求除了get和post还有什么呢?对了,就是文件的上传与下载。针对群里一些小伙伴需要得到当前的进度,所以下面会上整体的代码,我会在放完代码后做出解释。

文件上传

  public String uploadFile(String uploadUrl, File file) {
        if (httpUtils.isConnnected()) {
            RequestBody filebody = createProgressRequestBody(MEDIA_OBJECT_STREAM, file);
            RequestBody body = new MultipartBuilder().type(MultipartBuilder.FORM).addFormDataPart(file.getName(), file.getName(), filebody).build();
            Request request = new Request.Builder()
                    .url(uploadUrl)
                    .post(body)
                    .build();
            Response response = null;
            try {
                response = okHttpClient.newCall(request).execute();
                return response.body().string();
            } catch (IOException e) {

            }
        }
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  public RequestBody createProgressRequestBody(final MediaType contentType, final File file) {
        return new RequestBody() {
            public MediaType contentType() {
                return contentType;
            }

            public long contentLength() {
                return file.length();
            }

            public void writeTo(BufferedSink sink) throws IOException {
                Source source;
                try {
                    source = Okio.source(file);
                    Buffer buf = new Buffer();
                    long total = contentLength();
                    long current = 0;
                    for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
                        sink.write(buf, readCount);
                        current += readCount;
                        if (onProgressStateListener != null) {
                            onProgressStateListener.upload(byteUtils.getSize(current), byteUtils.getSize(total), byteUtils.getByte(current), byteUtils.getByte(total));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

此时你们会看到我判断了onProgressStateListener此接口不为空的情况,其实就是如果不需要得到当前的进度,我们就无需实现此接口。如果不需要得到进度,你也可以把上面createProgressRequestBody方法换成这句话:

 filebody=RequestBody.create(MEDIA_OBJECT_STREAM,file);
  • 1

文件下载

  Request request = new Request.Builder().url(httpDownloadBean.getUrl()).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                public void onResponse(Response response) {
                    InputStream inputStream = null;
                    try {
                        download_total = response.body().contentLength();
                        inputStream = response.body().byteStream();
                        if (response.isSuccessful()) {
                            writeSDFromInput(httpDownloadBean.getStoragepath(), httpDownloadBean.getFilepath(), inputStream);
                        } else {
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                public void onFailure(Request arg0, IOException arg1) {
                }
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里我们需要把inputstream写入sd卡:

 public File writeSDFromInput(String path, String fileName, InputStream input) {
        File file = null;
        OutputStream output = null;
        try {
            fileSupport.createSDDir(path);
            file = fileSupport.createSDFile(path + fileName);
            output = new FileOutputStream(file);
            byte buffer[] = new byte[1024];
            int length = 0;
            long current = 0;
            while ((length = input.read(buffer)) != -1) {
                current += length;
                if (onProgressStateListener != null) {
                    onProgressStateListener.download(byteUtils.getSize(current), byteUtils.getSize(download_total), byteUtils.getByte(current), byteUtils.getByte(download_total));
                }
                output.write(buffer, 0, length);
            }
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return file;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这里也和上传是一样的,你需要得到进度的时候实现此接口。

总结

Okhttp默认的配置为我们提供了非常重要实用功能。通过采用上述步骤,你可以增加它的灵活性和内省的能力并提高应用程序的质量。我对比过我用Httpclient和Okhttp的写的工具类,如果不需要得到进度的话,代码量差了一倍之多。从此而知,okhttp的确很好用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45616
推荐阅读
相关标签
  

闽ICP备14008679号