Android OKHttp使用简介

作者:Soybeanmilk 时间:2022-05-01 06:28:38 

目录
  • 配置

  • 创建OkHttpClient

  • 同步get请求

  • 异步get请求

  • 同步post请求

  • 异步post请求

  • 上传文件

  • 表单提交

下面是官网给出的OKHTTP的特点:

  1. 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据;

  2. 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时;

  3. 透明的Gzip处理降低了通信数据的大小

  4. 响应缓存完全避免了网络中的重复请求

  5. 使用Okio来简化数据的访问与存储,提高性能

  6. 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP

  7. OkHttp还处理了代理服务器问题和SSL握手失败问题;

官网地址:square.github.io/okhttp/

配置

添加OKHttp依赖


implementation 'com.squareup.okhttp3:okhttp:3.12.3'

添加网络权限,如果需要文件读写文件读写权限


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

接下来就可以愉快的开始使用OKhttp进行开发了。

创建OkHttpClient

OKhttpclient通过builder构建,构建的时候涉及到很多配置项,本次简单对其中一些配置项做了说明,后续会对一些重要的配置项做专题说明。在实际的项目中的配置项根据项目具体需求进行配置。


   OkHttpClient.Builder builder = new OkHttpClient.Builder();

//缓存目录
   File externalCacheDir = context.getExternalCacheDir();
   if (externalCacheDir != null) {
       Cache okHttpCache = new Cache(new File(externalCacheDir,
               "HttpCache"), 30 * 1024 * 1024);
       builder.cache(okHttpCache);
   }

//连接超时时间,连接超时是在将TCP SOCKET 连接到目标主机时应用的,默认10s
   builder.connectTimeout(30, TimeUnit.SECONDS);
   //读取超时时间, 包括TCP SOCKET和Source 和Response的读取IO操作,默认10s
   builder.readTimeout(20, TimeUnit.SECONDS);
   //写入超时时间,主要指IO的写入操作,默认10s
   builder.writeTimeout(20, TimeUnit.SECONDS);
   //整个调用时期的超时时间,包括解析DNS、链接、写入请求体、服务端处理、以及读取响应结果
   builder.callTimeout(120, TimeUnit.SECONDS);

//用于单个client监听所有解析事件的,可以用于解析耗时计算
   builder.eventListener(EventListener.NONE);

//添加 * ,框架内部已经默认添加了部分 * ,通过接口添加的 * 在列表首部
   builder.addInterceptor(new LogInterceptor());
   //添加网络 * ,网络 * 可以操作重定向和失败重连的返回值,以及监控所有的网络数据
   builder.addNetworkInterceptor(new NetworkInterceptor());

//在握手期间,如果URL的主机名和服务器的标识主机名不匹配,验证机制可以回调此接口的实现者,以确定是否应该允许此连接。
   //返回false表示不允许此链接,无脑return true 十分不安全
   builder.hostnameVerifier(new HostnameVerifier() {
       @Override
       public boolean verify(String hostname, SSLSession session) {
           return true;
       }
   });

//授权,默认为Authenticator.NONE
//        builder.authenticator(Authenticator.NONE);

//连接池,默认5个空闲连接,连接保活5分钟
//        builder.connectionPool(new ConnectionPool());

//自定义CookieJar,默认CookieJar.NO_COOKIES
//        builder.cookieJar(CookieJar.NO_COOKIES);

//调度策略,默认最大并发数默认为 64,但个域名最大请求数 默认为 5 个
//        builder.dispatcher(new Dispatcher());

//配置证书认证策略
//        builder.sslSocketFactory();

OkHttpClient  client = builder.build();

上述配置项中比较常用的有

  1. 缓存文件路径以及缓存的容量大小

  2. 网络请求的链接、读取、写入的超时时间

  3. * ,这个是OKHTTP最常用的,可以用于处理包括重试、缓存、日志打印等功能

  4. 域名和证书的校验

  5. 连接器以及并发的调度策略等

同步get请求


public void synGet(String url) {

// 第一步,构建HttpUrl
       HttpUrl.Builder builder = null;
       try {
           HttpUrl httpUrl = HttpUrl.parse(url);
           if(httpUrl != null){
               builder = httpUrl.newBuilder();
           }
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       }

if (builder == null) {
           return;
       }
       builder.addQueryParameter("key","value");

// 第二步,构建Request请求对象
       Request request = new Request.Builder()
               //请求地址
               .url(httpUrl)
               //get请求,默认为get请求
               .get()
               //添加请求头,一个key对应多个value,可以自定义
               .addHeader("key", "value")
               .addHeader("key", "value1")
               //请求头,一对一的,如常见的Content-Type、Accept-Encoding等
               .header("key1", "value1")
               //缓存策略,当前使用强制网络请求
               .cacheControl(CacheControl.FORCE_NETWORK)
               //缓存策略
               .build();

try {
           //第三步,开始进行同步请求
           Response response = client
                   .newCall(request)
                   .execute();

//第四步,解析响应结果
           ResponseBody body = response.body();
           if (body != null) {
               Log.d(TAG, body.string());
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

同步get请求会阻塞当前线程直到返回结果,请求大致分为四个步骤:

  1. 构建HttpUrl,当然这一步不是必须的,也可以直接传入地址

  2. 第二步,构建Request请求对象,可以设置请求头,缓存策略,请求方式

  3. 第三步,开始进行同步请求

  4. 解析响应结果

注意:同步get请求要在子线程中进行,否应用会抛异常。

异步get请求

异步请求方式的步骤和上述前两个步骤基本一致,主要发起请求的方式发生了变化,结果通过回调返回。这种请求方式对请求的线程没有限制。


// 第一步,构建HttpUrl
// 第二步,构建Request请求对象
//第三步,开始进行异步请求
client.newCall(request).enqueue(new Callback() {
           @Override
           public void onFailure(Call call, IOException e) {

}

@Override
           public void onResponse(Call call, Response response) throws IOException {
               //第四步,解析响应结果
               ResponseBody body = response.body();
               if (body != null) {
                   Log.d(TAG, body.string());
               }
           }
       });

同步post请求


public void synPost(String url) {
   // 第一步,构建HttpUrl
   HttpUrl.Builder builder = null;
   try {
       HttpUrl httpUrl = HttpUrl.parse(url);
       if (httpUrl != null) {
           builder = httpUrl.newBuilder();
       }
   } catch (IllegalArgumentException e) {
       e.printStackTrace();
   }
   if (builder == null) {
       return;
   }

//第二步,构建RequestBody
   MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
   JSONObject jsonObject = new JSONObject();
   try {
       jsonObject.put("key1", "value1");
       jsonObject.put("key2", "value2");
   } catch (JSONException e) {
       e.printStackTrace();
   }
   RequestBody requestBody = RequestBody.create(mediaType, jsonObject.toString());
   // 第三步,构建Request请求对象
   Request request = new Request.Builder()
           .url(builder.build())
           .post(requestBody)
           .build();

//第四步,开始进行同步post请求
   try {
       Response response = client.newCall(request).execute();
       //第五步,解析请求结果
       ResponseBody body = response.body();
       if (body != null) {
           Log.d(TAG, body.string());
       }
   } catch (IOException e) {
       e.printStackTrace();
   }
}

与get请求方式不同的是post请求需要构建RequestBody,在请求时携带RequestBody。

异步post请求


public void asynPost(String url) {
       // 第一步,构建HttpUrl
       //第二步,构建RequestBody
       // 第三步,构建Request请求对象
       Request request = new Request.Builder()
               .url(builder.build())
               .post(requestBody)
               .build();

client.newCall(request).enqueue(new Callback() {
           @Override
           public void onFailure(Call call, IOException e) {

}

@Override
           public void onResponse(Call call, Response response) throws IOException {
               ResponseBody body = response.body();
               if (body != null) {
                   Log.d(TAG, body.string());
               }
           }
       });
   }

上传文件


   //第一步,构建HttpUrl
   //第二步,构建RequestBody
   MediaType mediaType = MediaType.parse("multipart/form-data; charset=utf-8");
   RequestBody requestBody = RequestBody.create(mediaType, file);
//第三步,构建MultipartBody
   MultipartBody body = new MultipartBody.Builder()
           .setType(MultipartBody.FORM)
           //在此处添加多个requestBody实现多文件上传
           .addFormDataPart("file", file.getName(), requestBody)
           .build();

// 第四步,构建Request请求对象
   Request request = new Request.Builder()
           .url(builder.build())
           .post(body)
           .build();
// 第五步,构建Request请求对象
   client.newCall(request).enqueue(new Callback() {
       @Override
       public void onFailure(Call call, IOException e) {

}

@Override
       public void onResponse(Call call, Response response) throws IOException {
           ResponseBody body = response.body();
           if (body != null) {
               Log.d(TAG, body.string());
           }
       }
   });

表单提交


//第二步,构建RequestBody
   FormBody formBody = new FormBody.Builder()
           .add("key1","value1")
           .add("key2","value2")
           .build();

// 第三步,构建Request请求对象
   Request request = new Request.Builder()
           .url(builder.build())
           .post(formBody)
           .build();

client.newCall(request).enqueue(new Callback() {
       @Override
       public void onFailure(Call call, IOException e) {

}

@Override
       public void onResponse(Call call, Response response) throws IOException {
           ResponseBody body = response.body();
           if (body != null) {
               Log.d(TAG, body.string());
           }
       }
   });

来源:https://juejin.cn/post/6964638027683954695

标签:OKHttp,Android
0
投稿

猜你喜欢

  • Java实现文件上传到服务器本地并通过url访问的方法步骤

    2021-12-01 11:45:20
  • 在 Visual Studio 中查看反汇编代码

    2023-05-30 20:09:50
  • 使用HTTPclient保持长连接

    2023-10-17 12:29:34
  • java生成excel报表文件示例

    2023-02-27 13:17:49
  • photoView实现图片多点触控效果

    2023-06-21 20:16:03
  • Android教程之开机流程全面解析

    2023-02-18 21:02:44
  • Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)

    2022-04-14 03:32:22
  • java中gc算法实例用法

    2022-10-15 23:19:55
  • C# NetRemoting实现双向通信

    2022-07-01 14:05:58
  • Java聊天室之实现运行服务器与等待客户端连接

    2023-11-23 08:16:17
  • SpringBoot定时任务动态扩展ScheduledTaskRegistrar详解

    2023-04-23 08:44:06
  • 在IntelliJ IDEA中使用gulp的方法步骤(图文)

    2022-10-12 06:29:08
  • Java读取txt文件中的数据赋给String变量方法

    2022-08-04 22:32:19
  • Mybatis一对多查询的两种姿势(值得收藏)

    2023-07-01 00:20:08
  • java rocketmq--消息的产生(普通消息)

    2023-10-19 08:51:50
  • Java类和成员上的一些方法实例代码

    2022-03-15 10:47:31
  • java中 ${} 和 #{} 有什么区别

    2023-11-29 01:34:32
  • Spring事务管理配置文件问题排查

    2022-07-04 15:55:25
  • Java实现读取文章中重复出现的中文字符串

    2022-04-27 04:29:05
  • Spring Cloud之服务监控turbine的示例

    2023-04-20 23:26:44
  • asp之家 软件编程 m.aspxhome.com