Android jetbrains xcode rest selenium razor ssis wso2 vue插件 vue组件注册 bootstrap管理模板 前端项目实战 solr索引 matlab不等于 java二维数组赋值 wps文件修复工具下载 python命令 javaindexof java重写和重载 java写入txt java获取时间 m4a转mp3格式转换器 零基础学python 脚本之家官网 陌陌电脑直播设置教程 Mapper qq游戏黑名单 1500左右性价比最高的手机 WVS iphone组装机 cad周长快捷键 人物建模教程 键盘怎么调灯光 九宫格拼图 obs怎么设置 免费剪辑视频的软件 ps影子 我没钱表情包 nvme驱动下载 cad遮挡命令
当前位置: 首页 > 学习教程  > 编程语言

OkHttp(1)使用

2020/7/24 9:34:26 文章标签:

1.简介

HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个高效的HTTP客户端,它有以下默认特性:

支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接
连接池减少请求延时
透明的GZIP压缩减少响应数据的大小
缓存响应内容,避免一些完全重复的请求
当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。

2. 使用

它的请求/响应 API 使用构造器模式builders来设计,它支持阻塞式的同步请求和带回调的异步请求
添加依赖:

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

文件注册
在清单文件声明访问Internet的权限,如果使用 DiskLruCache,那还得声明写外存的权限

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

2.1 GET

在这里插入图片描述
在这里插入图片描述

2.2 POST

post和get的不同在于对Request请求的构造不同(因为post需要携带参数),post方式中的Request需要传递一个RequestBody作为post的参数。RequestBody有两个子类:FormBody和MultipartBody

2.3 表单键值对、String、流、文件、表单、分块请求

1.提交表单键值对
在这里插入图片描述
2.提交String
在构造 RequestBody 需要指定MediaType,用于描述请求/响应 body 的内容类型
在这里插入图片描述
3.提交流
在这里插入图片描述

4.提交文件
在这里插入图片描述

5.提交表单
提交表单时,使用 RequestBody 的实现类FormBody来描述请求体,它可以携带一些经过编码的 key-value 请求体,键值对存储在下面两个集合中:

  private final List<String> encodedNames;
  private final List<String> encodedValues;

在这里插入图片描述

6.提交分块请求
MultipartBody 可以构建复杂的请求体,与HTML文件上传形式兼容。多块请求体中每块请求都是一个请求体,可以定义自己的请求头。这些请求头可以用来描述这块请求,例如它的 Content-Disposition 。如果 Content-Length 和 Content-Type 可用的话,他们会被自动添加到请求头中。
在这里插入图片描述

2.4 拦截器

用户可传入的 interceptor 分为两类:
①一类是全局的 interceptor,该类 interceptor 在整个拦截器链中最早被调用,通过 OkHttpClient.Builder#addInterceptor(Interceptor) 传入;
②另外一类是非网页请求的 interceptor ,这类拦截器只会在非网页请求中被调用,并且是在组装完请求之后,真正发起网络请求前被调用,所有的 interceptor 被保存在 List< Interceptor > interceptors 集合中,按照添加顺序来逐个调用,具体可参考 RealCall#getResponseWithInterceptorChain() 方法。通过 OkHttpClient.Builder#addNetworkInterceptor(Interceptor) 传入;

例如有这样一个需求,我要监控App通过 OkHttp 发出的所有原始请求,以及整个请求所耗费的时间,针对这样的需求就可以使用第一类全局的 interceptor 在拦截器链头去做。

public class LoggingInterceptor implements Interceptor {
    private static final String TAG = "LoggingInterceptor";
    
    @Override
    public Response intercept(Chain chain) throws IOException {
        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 =  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;
    }
}

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(new LoggingInterceptor())
        .build();
Request request = new Request.Builder()
        .url("http://www.publicobject.com/helloworld.txt")
        .header("User-Agent", "OkHttp Example")
        .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 {
        ResponseBody body = response.body();
        if (body != null) {
            Log.d(TAG, "onResponse: " + response.body().string());
            body.close();
        }
    }
});
Sending request http://www.publicobject.com/helloworld.txt on null
User-Agent: OkHttp Example
      
Received response for https://publicobject.com/helloworld.txt in 1265.9ms
Server: nginx/1.10.0 (Ubuntu)
Date: Wed, 28 Mar 2018 08:19:48 GMT
Content-Type: text/plain
Content-Length: 1759
Last-Modified: Tue, 27 May 2014 02:35:47 GMT
Connection: keep-alive
ETag: "5383fa03-6df"
Accept-Ranges: bytes

2.5 推荐让 OkHttpClient 保持单例

用同一个 OkHttpClient 实例来执行你的所有请求,因为每一个 OkHttpClient 实例都拥有自己的连接池和线程池,重用这些资源可以减少延时和节省资源,如果为每个请求创建一个 OkHttpClient 实例,显然就是一种资源的浪费。当然,也可以使用如下的方式来创建一个新的 OkHttpClient 实例,它们共享连接池、线程池和配置信息。

OkHttpClient eagerClient = client.newBuilder()
    .readTimeout(500, TimeUnit.MILLISECONDS)
    .build();
Response response = eagerClient.newCall(request).execute();

本文链接: http://www.dtmao.cc/news_show_50130.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?