OkHttp的使用

来源:互联网 发布:python的sin 编辑:程序博客网 时间:2024/06/05 03:43

OkHttp的使用

一、添加依赖

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

二、简单使用

OkHttp使用步骤可以总结为:

  • 1.创建OkHttpClient对象
  • 2.构造Request
  • 3.将Request封装为Call
  • 4.执行call(异步\同步请求)拿到Response

2.1 get请求

例子描述:发起get请求获取网页内容

OkHttpClient可以设置一些全局信息,例如连接超时时间等,具体可设置参数可以通过源码查看。Request.Builder()提供了一些方法可以设置一些参数,例如header()、method()等。

如果是执行同步请求:

如果是执行异步请求:

关于Response的注意点:

  • 1.虽然OkHttp通过enqueue方法开启了一个子线程进行了请求,但是回调的onFailure和onResponse方法仍然还是在那个子线程里,所以在Response的回调方法里,不能直接更新UI。
  • 2.response.isSuccessful():如果code在[200,300)中返回true,这意味着请求被成功接收、理解和接受。
  • 3.如果希望返回的是字符串,使用response.body().string()获取;如果希望返回的是二进制数组,使用response.body().bytes()获取;如果希望返回的是inputStream,使用response.body().byteStream()获取。

2.2 post请求

例子描述:提交用户信息

与get请求不同的是,post请求的参数是包含在请求体中的。查看post请求源码:

需要传入一个RequestBody。我们可以通过FormBody.Builder()的add(String name, String value)方法来构建一个RequestBody。

之后就与get请求一样了,此后不在赘述。

2.3 post一个Json字符串

备注:post方法的使用步骤大致一样,唯一的不同是构造RequestBody,下面着重构造RequestBody。

例子描述:提交Json格式字符串

RequestBody提供了一些静态方法,支持传入一写常见数据格式。

其中,post String的方法需要传入两个参数,一个是MediaType,一个是String。MediaType包含一个类型,和一个字符编码。指定MediaType的类型为普通文本,字符编码为utf-8。

其他常见格式大致相同,只是MediaType不同,不同数据格式的MediaType,可以百度mime type。链接地址:
http://www.w3school.com.cn/media/media_mimeref.asp

例如:Post一个File

2.4 post文件且携带参数

多类型数据组合的数据需要用到MultipartBody来构建。

例子描述:上传用户信息和文件(例如用户头像)

2.5 下载文件

和get方法类似,主要不同体现在数据解析上。

例子描述:下载一张图片,保存在SD卡。


2.6 加载图片

例子描述:拿到response后,直接将图片显示到控件上。

图片处理:1.下载到本地后,再二次采样。2.直接二次采样。

2.7 进度问题

2.7.1 下载进度

在文件下载的地方加入几行代码即可:

2.7.2 上传进度

RequestBody并没有提供相关方法,而BufferedSink有方法可以拿到byteCount。

网络上有个方案,定义一个CountingRequestBody类,对原有的RequestBody进行封装。

package com.tiddlerliu.oktest;import android.support.annotation.Nullable;import java.io.IOException;import okhttp3.MediaType;import okhttp3.RequestBody;import okio.Buffer;import okio.BufferedSink;import okio.ForwardingSink;import okio.Okio;import okio.Sink;public class CountingRequestBody extends RequestBody {    protected RequestBody delegate;//RequestBody代理    private Listener listener;//回调接口    protected CountingSink countingSink;    public CountingRequestBody(RequestBody requestBody,Listener listener){    delegate = requestBody;    this.listener = listener;    }    @Nullable    @Override    public MediaType contentType() {    return delegate.contentType();    }    @Override    public long contentLength() {    try {        return delegate.contentLength();    } catch (IOException e) {        return -1;    }    }    @Override    public void writeTo(BufferedSink sink) throws IOException {    countingSink = new CountingSink(sink);//封装sink    BufferedSink bufferedSink = Okio.buffer(countingSink);//将CountingSink包装为BufferedSink    delegate.writeTo(bufferedSink);    bufferedSink.flush();//刷新    }    /**     * 封装Sink     */    protected final class CountingSink extends ForwardingSink{    private long bytesWritten;    public CountingSink(Sink delegate) {        super(delegate);    }    @Override    public void write(Buffer source, long byteCount) throws IOException {        super.write(source, byteCount);        bytesWritten += byteCount;        listener.onRequestProgress(bytesWritten,contentLength());//将byteCount和contentLength回调出去    }    }    /**     * 回调接口     */    public static interface Listener{    void onRequestProgress(long byteWritten,long contentLength);//已写字节数,总共字节数    }}

使用也很简单,使用CountingRequestBody对RequestBody再次进行封装即可。

2.8 sessionID过期问题

先占个坑,后续添加。

三、常见问题

3.1 response

response 只能用一次,这一次使用的机会包含log,包含log,包含log 。response.body().string()转换为string,适用于内容小于1m的。

原创粉丝点击