OkHttp3最佳入门使用

在OkHttp以前大家普遍使用Volley、asyncHttpClient、HttpURLConnection来作为我们应用的网络框架。但是相比于他们OkHttp有什么优点呢?我们看官方给出的介绍:

  • HTTP/2 support allows all requests to the same host to share a socket.
  • Connection pooling reduces request latency (if HTTP/2 isn’t available).
  • Transparent GZIP shrinks download sizes.
  • Response caching avoids the network completely for repeat requests.

从上面的介绍我们可以看出OkHttp相比于之前我们使用的网络框架,有这些不一样的地方。1、支持http2(支持SPDY),允许所有请求公用一个socket。2、使用连接池减少请求延迟(不支持http2)3、透明的Gzip压缩 4、利用响应缓存来避免重复的网络请求。此外谷歌在 android api 26将httpclient移除,加入了OkHttp。下面简单讲一下OkHttp3的使用:

一、添加依赖和网络权限

//网络请求依赖
api 'com.squareup.okhttp3:okhttp:3.10.0'
api 'com.squareup.okio:okio:1.14.0'
//添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

二、简单使用

1、发送GET请求

@Test
public void testGet(){
    //创建OkHttpClient实例对象
    OkHttpClient okHttpClient = new OkHttpClient();
    //创建Request对象
    Request request = new Request.Builder()
            .url("https://www.httpbin.org/get?id=111")
            .addHeader("key","value")
            .get()
            .build();
    //执行Request请求
    //异步请求
    /*okHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            //请求失败
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //请求成功
            Log.d("TestOkHttp",response.body().string());
        }
    });*/
    //同步请求
    try {
        Response response = okHttpClient.newCall(request).execute();
        System.out.println(response.body().string());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

测试一下:
这里写图片描述

2、发送POST请求

与get请求的不同之处需要顶一个RequestBody

@Test
public void testPost(){
    //1、创建OkHttpClient对象实例
    OkHttpClient okHttpClient = new OkHttpClient();
    //2、创建Request对象
    MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
    RequestBody requestBody = RequestBody.create(mediaType,"{}");
    Request request = new Request.Builder()
            .url("https://www.httpbin.org/post")
            .post(requestBody)
            .build();
    //3、执行Request请求
    try {
        Response response = okHttpClient.newCall(request).execute();
        System.out.println(response.body().string());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这里写图片描述
总结一下:
基本就是一下三步 1、创建OkHttpClient对象实例;2、创建你需要的Request对象,如果是post请求需要添加RequestBody;3、使用OkHttpClient对象实例执行请求,得到Response对象。

更多详细的请求方式,请看官方的介绍。https://github.com/square/okhttp/wiki/Recipes

三、添加拦截器

这里写图片描述
上面是一张官网对OkHttp拦截器的介绍,形象的解释了Application interceptorsNetwork Interceptors之间的区别。
下面是两者之间相对优势的介绍

Each interceptor chain has relative merits.
Application interceptors
1、Don’t need to worry about intermediate responses like redirects and retries.
2、Are always invoked once, even if the HTTP response is served from the cache.
3、Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
4、Permitted to short-circuit and not call Chain.proceed().
5、Permitted to retry and make multiple calls to Chain.proceed().
.
Network Interceptors
1、Able to operate on intermediate responses like redirects and retries.
2、Not invoked for cached responses that short-circuit the network.
3、Observe the data just as it will be transmitted over the network.
4、Access to the Connection that carries the request.

翻译过来大概是:
Application Interceptor

  • 不用关心redirects和reties的Response中间的过程
  • 永远只会调用一次,不管Http Response是否是从缓存中直接取到的
  • 可以监控原始的请求,不关心其它诸如If-None-Match的Header
  • 允许不调用Chain.proceed()
  • 允许重试多次调用Chain.proceed()。

Network Interceptors

  • 可以操作redirects和reties的过程
  • 不会调用缓存的Response
  • 可以监控网络传输交互的数据
  • 可以获取Connection携带的请求信息

区别在于:Application Interceptor能拦截所有类型的请求,包括缓存命中的请求;而Network Interceptors仅拦截非WebSocket的情况下产生真正网络访问的请求。因此在Network Interceptors上做网络上传和下载进度的监听器是比较合适的。

@Test
public void testInterceptor(){
    Interceptor loggingInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Logger logger = Logger.getGlobal();
            //我这里参考的是官网的,你也可以定义里自己的打印方式
            long t1 = System.nanoTime();
            logger.info(String.format("Sending request %s on %s%n%s",
                    request.url(), chain.connection(), request.headers()));
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();
            logger.info(String.format("Received response for %s in %.1fms%n%s",
                    response.request().url(), (t2 - t1) / 1e6d, response.headers()));
            return response;
        }
    };
    //1、创建OkHttpClient实例对象
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                //.addNetworkInterceptor() // 添加网络拦截器
                .build();
    //2、创建Request实例对象
    Request request = new Request.Builder()
            .url("https://www.httpbin.org/get?id=111")
            .get()
            .build();
    //3、使用client执行request请求
    try {
        Response response = okHttpClient.newCall(request).execute();
        System.out.println(response.body().string());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这里写图片描述

使用拦截器模拟数据

public class FakeApiInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response;
        if (BuildConfig.DEBUG && chain.request().url().toString().equals(API_URL)) {
            String json = "{\"code\": 200, \"message\": \"success\"}";
            response = new Response.Builder()
                    .code(200)
                    .addHeader("Content-Type", "application/json")
                    .body(ResponseBody.create(MediaType.parse("application/json"), json))
                    .message(json)
                    .request(chain.request())
                    .protocol(Protocol.HTTP_2)
                    .build();
        } else {
            response = chain.proceed(chain.request());
        }
        return response;
    }
}

四、添加缓存处理

@Test
public void testCache(){
    Cache cache = new Cache(new File(Environment.getDataDirectory(),"cache"),10*1024*1024);
    //1、创建OkHttpClient实例对象
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .cache(cache)
            .build();
    //2、创建Request实例对象
    Request request = new Request.Builder()
            .url("")
            .get()
            .build();
    //3、使用client执行Request请求
    try {
        Response response = okHttpClient.newCall(request).execute();
        //从缓存中获取响应
        Response cacheResponse = response.cacheResponse();
        //从网络中获取响应
        Response networkResponse = response.networkResponse();
        System.out.println(response.body().string());
        System.out.println(cacheResponse.body().string());
        System.out.println(networkResponse.body().string());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

猜你喜欢

转载自blog.csdn.net/dingshuhong_/article/details/80335499