美文网首页
Okhttp3入门

Okhttp3入门

作者: Sharkchilli | 来源:发表于2020-12-25 19:27 被阅读0次

官网介绍

HTTP是现代应用程序网络的方式。这就是我们交换数据和媒体的方式。有效地执行HTTP可使您的内容加载更快并节省带宽。

OkHttp是默认情况下有效的HTTP客户端:

  • HTTP / 2支持允许对同一主机的所有请求共享一个套接字。
  • 连接池可减少请求延迟(如果HTTP / 2不可用)。
  • 透明的GZIP缩小了下载大小。
  • 响应缓存可以完全避免网络重复请求。

使用

okhttp的使用就是下面这张图


image.png

1.创建OkHttpClient工厂(可以直接new也可以使用new OkHttpClient.Builder().build()方式构建,后者可以添加更多配置)
2.创建要发送的请求Request(指定post还是get 给定url 配置header等工作)
3.构建真正发送请求的Call(okHttpClient.newCall(request))
4.最后使用execute或enqueue发送请求(前者是同步后者是异步)

异步get

//异步get
    public void AsynchronousGet() {
        String url = "http://wwww.baidu.com";
        OkHttpClient okHttpClient = new OkHttpClient();
        //构建一个Request请求,在这里指定它的参数
        Request request = new Request.Builder()
                .url(url)
                .get()//默认就是GET请求,可以不写
                .build();
        //使用OkHttpClient创建出真正可以执行Call
        Call realCall = okHttpClient.newCall(request);
        //发送异步请求
        realCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, "onResponse: " + response.body().string());
            }
        });
    }

这里的步骤和上面说的一样最后使用enqueue方法发送异步请求,请求处理在Callback回调类中的onResponse方法和onFailure方法做处理

同步get

public void SynchronousGet() {
        String url = "http://wwww.baidu.com";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        final Call call = okHttpClient.newCall(request);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response response = call.execute();
                    Log.d(TAG, "run: " + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

同步操作并没有很大区别,最后调用的是execute方法,这个方法不接受回调直接返回Response对象。注意的是这个同步操作不能在ui线程去做所以这里我开了个子线程.

post

public void post() {
        //创建MediaType,用于描述请求/响应 body 的内容类型
        MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
        String msg = "I am shark.";
        //创建RequestBody
        RequestBody requestBody = RequestBody.create(mediaType, msg);

        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(requestBody)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                Log.d(TAG, "onResponse: " + response.body().string());
            }
        });
    }

post方法在构建Request的时候指定,它和get不同的是需要一个RequestBody 参数,这个参数我们可以使用RequestBody.create生成,它需要指定这个请求体的类型MediaType ,可以使用 MediaType.parse获得MediaType

post提交表单

//post提交表单
    public void postForm() {
        OkHttpClient okHttpClient = new OkHttpClient();
        
        FormBody requestBody = new FormBody.Builder()
                .add("testname", "testval")
                .build();
        Log.d(TAG, " requestBody.encodedName(0) " + requestBody.encodedName(0));

        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(requestBody)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                Log.d(TAG, "onResponse: " + response.body().string());
            }
        });
    }

想要在post请求加入表单就要使用RequestBody的子类FormBody。Builder()方法后使用add("key","val")就能添加参数了。

再说明一点FormBody的name和val是存放在下面的两个List中的

public static final class Builder {
    private final List<String> names = new ArrayList<>();
    private final List<String> values = new ArrayList<>();

Interceptor拦截器

我们可以在一个请求发送前和发送后去拦截到它,并对其进行操作。这里okhttp3提供了Interceptor。这玩意很像struts2的拦截器。

首先我们自定义一个我们自己的拦截器,需要继承Interceptor

public class LoggingInterceptor implements Interceptor {
    private static final String TAG = "LoggingInterceptor";

    @Override
    public Response intercept(Chain chain) throws IOException {
        //获得Request
        Request request = chain.request();

        long startTime = System.nanoTime();
        Log.d(TAG, String.format("Sending request %s on %s%n%s",
                request.url(), chain.connection(), request.headers()));
        //继续发送请求的操作,也就是发送请求 最后能得到Response
        Response response =  chain.proceed(request);

        long endTime = System.nanoTime();
        Log.d(TAG, String.format("Received response for %s in %.1fms%n%s",
                response.request().url(), (endTime - startTime) / 1e6d, response.headers()));

        return response;
    }
}

调用chain.proceed(request)是每个拦截器实现的关键部分,它会继续我们请求的后续操作。这样在这之后的代码就是请求回来后才会执行的了。

在构建OkHttpClient的时候配置Interceptor

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new LoggingInterceptor())
                .build();

尾言

Okhttp3使用还是很简单的,不太清楚的地方可以查阅官方文档
https://square.github.io/okhttp/interceptors/

相关文章

网友评论

      本文标题:Okhttp3入门

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