当前位置:   article > 正文

Android技能必备之Okhttp3_android okhttpclient accept-encoding

android okhttpclient accept-encoding

前言

想要使用retrofit2或者Okgo等网络框架,熟悉并且掌握Okhttp3是很有必要的。HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个高效的HTTP客户端,它有一下特性:

  • http/2支持所有同一个主机地址的请求分享相同的socket通道
  • 连接池减少请求延时
  • GZIP压缩减少下载数据
  • 缓冲响应内容,避免重复请求

导入依赖

首先在清单文件声明internet访问权限,然后导入依赖:

implementation("com.squareup.okhttp3:okhttp:4.2.2")

异步get请求

步骤如下:

  1. 创建url
  2. 实例OkHttpClient
  3. 创建Request请求
  4. 调用客户端的回调构建Call
  5. 通过call的enqueue来提交异步请求
  1. String url = "http://wwww.baidu.com";
  2. OkHttpClient okHttpClient = new OkHttpClient();
  3. final Request request = new Request.Builder()
  4. .url(url)
  5. .get()//默认就是GET请求,可以不写
  6. .build();
  7. Call call = okHttpClient.newCall(request);
  8. call.enqueue(new Callback() {
  9. @Override
  10. public void onFailure(Call call, IOException e) {
  11. Log.d(TAG, "onFailure: ");
  12. }
  13. @Override
  14. public void onResponse(Call call, Response response) throws IOException {
  15. Log.d(TAG, "onResponse: " + response.body().string());
  16. }
  17. });

异步post请求

步骤如下:

  1. 创建url
  2. 创建OkHttpClient
  3. 创建Request,其中请求中需要在RequestBody中上传数据,所以需要指定MediaType,用于描述请求体的类型
  4. 调用客户端的回调构建Call
  5. 通过Call的enqueue来提交异步请求
  1. MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
  2. String requestBody = "hello kitty";
  3. Request request = new Request.Builder()
  4. .url("https://api.github.com/markdown/raw")
  5. .post(RequestBody.create(mediaType, requestBody))
  6. .build();
  7. OkHttpClient okHttpClient = new OkHttpClient();
  8. okHttpClient.newCall(request).enqueue(new Callback() {
  9. @Override
  10. public void onFailure(Call call, IOException e) {
  11. Log.d(TAG, "onFailure: " + e.getMessage());
  12. }
  13. @Override
  14. public void onResponse(Call call, Response response) throws IOException {
  15. Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
  16. Headers headers = response.headers();
  17. for (int i = 0; i < headers.size(); i++) {
  18. Log.d(TAG, headers.name(i) + ":" + headers.value(i));
  19. }
  20. Log.d(TAG, "onResponse: " + response.body().string());
  21. }
  22. });

同步get请求

同步与异步请求的区别在于同步请求是提交请求之后会在同一个线程等待请求结果,是一个耗时操作,所以只能放在子线程中来执行,并且通过call.execute()来提交同步请求。

  1. String url = "http://wwww.baidu.com";
  2. OkHttpClient okHttpClient = new OkHttpClient();
  3. final Request request = new Request.Builder()
  4. .url(url)
  5. .build();
  6. final Call call = okHttpClient.newCall(request);
  7. new Thread(new Runnable() {
  8. @Override
  9. public void run() {
  10. try {
  11. Response response = call.execute();//需要放在子线程中
  12. Log.d(TAG, "run: " + response.body().string());
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }).start();

拦截器interceptor

Application Interceptor

拦截器主要在两个地方使用,一个作为全局变量使用,也叫Application Interceptor,通过OkHttpClient.Builder() .addInterceptor()传入

  1. OkHttpClient client = new OkHttpClient.Builder()
  2. .addInterceptor(new LoggingInterceptor())
  3. .build();
  4. Request request = new Request.Builder()
  5. .url("http://www.publicobject.com/helloworld.txt")
  6. .header("User-Agent", "OkHttp Example")
  7. .build();
  8. Response response = client.newCall(request).execute();
  9. response.body().close();

上面调用的是日志拦截器,拦截器会被调用一次,并通过chain.procced()来接收响应数据。

  1. class LoggingInterceptor implements Interceptor {
  2. @Override public Response intercept(Interceptor.Chain chain) throws IOException {
  3. Request request = chain.request();
  4. long t1 = System.nanoTime();
  5. logger.info(String.format("Sending request %s on %s%n%s",
  6. request.url(), chain.connection(), request.headers()));
  7. Response response = chain.proceed(request);
  8. long t2 = System.nanoTime();
  9. logger.info(String.format("Received response for %s in %.1fms%n%s",
  10. response.request().url(), (t2 - t1) / 1e6d, response.headers()));
  11. return response;
  12. }
  13. }

拦截器响应结果

  1. INFO: Sending request http://www.publicobject.com/helloworld.txt on null
  2. User-Agent: OkHttp Example
  3. INFO: Received response for https://publicobject.com/helloworld.txt in 1179.7ms
  4. Server: nginx/1.4.6 (Ubuntu)
  5. Content-Type: text/plain
  6. Content-Length: 1759
  7. Connection: keep-alive

可以看到发送请求和接收请求的url是不一样的,这是因为Okhttp会自动根据发送的url做重定向。

Network Interceptors

注册网络拦截器与上面的方法相似,调用addNetworkInterceptor()

  1. OkHttpClient client = new OkHttpClient.Builder()
  2. .addNetworkInterceptor(new LoggingInterceptor())
  3. .build();
  4. Request request = new Request.Builder()
  5. .url("http://www.publicobject.com/helloworld.txt")
  6. .header("User-Agent", "OkHttp Example")
  7. .build();
  8. Response response = client.newCall(request).execute();
  9. response.body().close();

这里的拦截器调用两次,一次初始化请求http://www.publicobject.com/helloworld.txt,另外一次重定向为https://publicobject.com/helloworld.txt.

  1. INFO: Sending request http://www.publicobject.com/helloworld.txt on Connection{www.publicobject.com:80, proxy=DIRECT hostAddress=54.187.32.157 cipherSuite=none protocol=http/1.1}
  2. User-Agent: OkHttp Example
  3. Host: www.publicobject.com
  4. Connection: Keep-Alive
  5. Accept-Encoding: gzip
  6. INFO: Received response for http://www.publicobject.com/helloworld.txt in 115.6ms
  7. Server: nginx/1.4.6 (Ubuntu)
  8. Content-Type: text/html
  9. Content-Length: 193
  10. Connection: keep-alive
  11. Location: https://publicobject.com/helloworld.txt
  12. INFO: Sending request https://publicobject.com/helloworld.txt on Connection{publicobject.com:443, proxy=DIRECT hostAddress=54.187.32.157 cipherSuite=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA protocol=http/1.1}
  13. User-Agent: OkHttp Example
  14. Host: publicobject.com
  15. Connection: Keep-Alive
  16. Accept-Encoding: gzip
  17. INFO: Received response for https://publicobject.com/helloworld.txt in 80.9ms
  18. Server: nginx/1.4.6 (Ubuntu)
  19. Content-Type: text/plain
  20. Content-Length: 1759
  21. Connection: keep-alive

网络请求包含更多的数据,包括显示Accept-Encoding: gzip,这是Okhttp对于压缩响应数据的的支持。

Application Interceptor和Network Interceptors之间的异同之处

Application Interceptor

  • 不用担心响应的重定向或者重试问题
  • 总是唤醒一次,即使来自缓存服务的http响应也是一样的
  • 遵守应用程序的原始意图。 不关心OkHttp注入的头信息,如If-None-Match。
  • 可以中断调用并且有权决定是否执行Chain.proceed()。
  • 允许重连和多次调用Chain.proceed()。

Network Interceptors

  • 能够对诸如重定向和重试之类的中间响应进行操作。
  • 不会调用网络的缓存响应。
  • 观察在网络传输时的数据变化,如重定向
  • 携带请求来访问连接

Okhttp github地址:https://github.com/square/okhttp

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45658?site
推荐阅读
相关标签
  

闽ICP备14008679号