美文网首页
Android OKhttp笔记 整体分析

Android OKhttp笔记 整体分析

作者: silencefun | 来源:发表于2020-03-05 13:11 被阅读0次

以前做的笔记一半 现在在补充 update time:2020年3月5日 12:04:56
Anroid OKhttp笔记1 流程分析
Android OkhttpInterceptor 笔记:RetryAndFollowUpInterceptor
Android OkhttpInterceptor 笔记:BridgeInterceptor
Android OkhttpInterceptor 笔记:ConnectInterceptor
Android OkhttpInterceptor 笔记:CacheInterceptor
Android OkhttpInterceptor 笔记:CallServerInterceptor
Android Okhttp笔记:ConnectionPool
Android Okhttp3:Dispatcher分析笔记


一、github地址、使用

OkHttp的GitHub地址是:OkHttp
OkIo的GitHub地址是:OkIo
使用,

dependencies {
//...
//OkHttp
implementation 'com.squareup.okhttp3:okhttp:3.14.2'
implementation 'com.squareup.okio:okio:1.17.4'
}

注意:OkHttp在3.13.x以上的版本需要在Android 5.0+ (API level 21+)和Java 1.8的环境开发。

同时还需要再添加Okio的依赖库,而Okio在1.x版本是基于Java实现的,2.x则是Kotlin实现的。

二、关键类和方法

OkHttpClient:客户端对象
Request:访问请求,Post请求中需要包含RequestBody
RequestBody:请求数据,在Post请求中用到
Response:即网络请求的响应结果
Interceptor:拦截器,能够监控,重写以及重试(请求的)调用。
MediaType:数据类型,用来表明数据是json,image,pdf等一系列格式
client.newCall(request).execute():同步的请求方法
client.newCall(request).enqueue(Callback callBack):异步的请求方法

注意:1.Callback是执行在子线程中的,因此不能在此进行UI更新操作;
2.okhttp2.2以后才有拦截器的概念,2.2以后经过了一次代码重构,加入了拦截器机制(已经很久之前的事情了).

三、使用:同步/异步、get/post

1.同步get,需要自己起个子线程来进行请求

public void getSyn(final String url) {
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            //创建OkHttpClient对象
            OkHttpClient client = new OkHttpClient();
            //创建Request
            Request request = new Request.Builder()
                    .url(url)//访问连接
                    .get().build();
            //创建Call对象        
            Call call = client.newCall(request);
            //通过execute()方法获得请求响应的Response对象        
            Response response = call.execute();
            if (response.isSuccessful()) {
                //处理网络请求的响应,处理UI需要在UI线程中处理
                //...
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
}

2.异步get

public void getAsyn(String url) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        //...
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if(response.isSuccessful()){
            String result = response.body().string();
            //处理UI需要切换到UI线程处理
        }
    }
 });
}

说明:

  'Request.Builder'中默认的使用Get请求,所以可以不调用get()方法

3.post请求

         //1.创建OkHttpClient对象
    OkHttpClient okHttpClient = new OkHttpClient();
    //RequestBody中的MediaType指定为纯文本,编码方式是utf-8
    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),
            "{username:admin;password:admin}");
    //2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
    Request request = new Request.Builder()
          .url("http://www.baidu.com")
          .post(requestBody )
          .build();
    //3.创建一个call对象,参数就是Request请求对象
    Call call = okHttpClient.newCall(request);
    //4.请求加入调度,重写回调方法
    call.enqueue(new Callback() {
        //请求失败执行的方法
        @Override
        public void onFailure(Call call, IOException e) {
            String err = e.getMessage().toString();
        }
        //请求成功执行的方法
        @Override
        public void onResponse(Call call, Response response) throws IOException {
              final String rtn = response.body().string();
              //获取返回码
              final String code = String.valueOf(response.code())
              runOnUiThread(new Runnable() {
                @Override
                public void run() {
                }
              );
        }
    });

其中 RequestBody 可以是JSON 、表单、键值对、文件等,

  RequestBody body = RequestBody.create(JSON, json);

表单

 MultipartBody.Builder mBuild = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("username", "xxx")
            .addFormDataPart("password", "xxx");
    RequestBody requestBody= mBuild.build();  

注意:无论是同步还是异步请求,接收到Response对象时均在子线程中,其中通过Response对象获取请求结果需要在子线程中完成,在得到结果后再切换到UI线程改变UI

四、请求流程

从上面的请求例子可以看出来,基本流程都是先创建一个OkHttpClient对象,然后通过Request.Builder()创建一个Request对象,OkHttpClient对象调用newCall()并传入Request对象就能获得一个Call对象。而同步和异步不同的地方在于execute()和enqueue()方法的调用,调用execute()为同步请求并返回Response对象;调用enqueue()方法测试通过callback的形式返回Response对象。

其中execute()及enqueue()这两个方法会最终调用RealCall中的getResponseWithInterceptorChain()方法,从拦截器链中获取返回结果; 拦截器链中,依次通过RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor对请求依次处理,与服务的建立连接后,获取返回数据,再经过上述拦截器依次处理后,最后将结果返回给调用方。

图片来源于网络

五、拦截器

0.Interceptor是啥,有啥用?

来自官网的英文原文:

 Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.

拦截器是一个强有力的机制,能够监控,重写以及重试调用。

拦截器的作用就是:可以在应用拿到response之前,先获得response,对其中某些数据进行监控,在有必要的情况下,对response的某些内容(比如response的header,body,response内的request的header,body)进行更改。

1.okhttp内的拦截器

重试及重定向拦截器 RetryAndFollowUpInterceptor 负责请求的重试和重定向

桥接拦截器 BridgeInterceptor 给请求添加对应的 header 信息,处理响应结果的 header 信息

缓存拦截器 CacheInterceptor 根据当前获取的状态选择 网络请求 、读取缓存、更新缓存。

连接拦截器 ConnectInterceptor 建立 http 连接。

读写拦截器 CallServerInterceptor 通过连接好的通道进行数据的交换;

2.自定义拦截器

okhttp自定义的拦截器分为两类:

1)ApplicationInterceptor(应用拦截器)

2)NetworkInterceptor(网络拦截器)

应用拦截器作用于okhttpCore到Application之间,网络拦截器作用于 network和okhttpCore之间,添加应用拦截器的接口是addInterceptor(),而添加网络拦截器的接口是addNetworkInterceptor().

3.应用场景

NetworkInterceptor:记录日志,
ApplicationInterceptor:动态添加请求公共参数,检查请求路径权限(比如是否登录状态)。

说明:在某种特殊情况下(比如:访问了一个url,结果这个url发生了重定向),网络拦截器有可能被执行多次,但是 不论任何情况,application只会被执行一次。

六、其他设置

1.请求头

请求的Header是通过Request.Builder对象的相关方法来维护的,如下:

headers(Headers headers)
header(String name, String value)
addHeader(String name, String value)
removeHeader(String name)

addHeader和removeHeader方法比较好理解,分别是添加和移除header信息。header(String name, String value)这是会重新设置指定name的header信息。

headers(Headers headers)则是会移除掉原有的所有header信息,将参数headers的header信息添加到请求中。这是这几个方法的一些差别。

2.时间相关

OkHttp可以设置调用、连接和读写的超时时间,都是通过OkHttpClient.Builder设置的。如果不主动设置,OkHttp将使用默认的超时设置。

OkHttpClient mClient = new OkHttpClient.Builder()
    .callTimeout(6_000, TimeUnit.MILLISECONDS)
    .connectTimeout(6_000, TimeUnit.MILLISECONDS)
    .readTimeout(20_000, TimeUnit.MILLISECONDS)
    .writeTimeout(20_000, TimeUnit.MILLISECONDS)
    .build();

Anroid OKhttp笔记1 流程分析
Android OkhttpInterceptor 笔记:RetryAndFollowUpInterceptor
Android OkhttpInterceptor 笔记:BridgeInterceptor
Android OkhttpInterceptor 笔记:ConnectInterceptor
Android OkhttpInterceptor 笔记:CacheInterceptor
Android OkhttpInterceptor 笔记:CallServerInterceptor
Android Okhttp笔记:ConnectionPool
Android Okhttp3:Dispatcher分析笔记

相关文章

网友评论

      本文标题:Android OKhttp笔记 整体分析

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