Android使用OKHttp包处理HTTP相关操作的基本用法讲解_Android

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势。(GitHub页:https://github.com/square/okhttp)

Android为我们提供了两种HTTP交互的方式:HttpURLConnection 和 Apache HTTP Client,虽然两者都支持HTTPS,流的上传和下载,配置超时,IPv6和连接池,已足够满足我们各种HTTP请求的需求。但更高效的使用HTTP 可以让您的应用运行更快、更节省流量。而OkHttp库就是为此而生。
OkHttp是一个高效的HTTP库:

  • 支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求
  • 如果SPDY不可用,则通过连接池来减少请求延时
  • 无缝的支持GZIP来减少数据流量
  • 缓存响应数据来减少重复的网络请求
  • 会从很多常用的连接问题中自动恢复。

如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。
使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

引入
可以通过下载jar包直接导入工程地址
或者通过构建的方式导入
MAVEN:

<dependency>
 <groupId>com.squareup.okhttp</groupId>
 <artifactId>okhttp</artifactId>
 <version>2.4.0</version>
</dependency>

GRADLE:

compile 'com.squareup.okhttp:okhttp:2.4.0'

用法
在向网络发起请求的时候,我们最常用的就是GET和POST,下面就来看看如何使用
1. GET
在OKHttp,每次网络请求就是一个Request,我们在Request里填写我们需要的url,header等其他参数,再通过Request构造出Call,Call内部去请求参数,得到回复,并将结果告诉调用者。

package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
  private final static String TAG = "TestActivity";
  private final OkHttpClient client = new OkHttpClient();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          execute();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();
  }
  public void execute() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response = client.newCall(request).execute();
    if(response.isSuccessful()){
      System.out.println(response.code());
      System.out.println(response.body().string());
    }
  }
}

我们通过Request.Builder传入url,然后直接execute执行得到Response,通过Response可以得到code,message等信息。
这个是通过同步的方式去操作网络请求,而android本身是不允许在UI线程做网络请求操作的,因此我们需要自己开启一个线程。
当然,OKHttp也支持异步线程并且有回调返回,有了上面同步的基础,异步只要稍加改动即可

private void enqueue(){
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    client.newCall(request).enqueue(new Callback() {
      @Override
      public void onFailure(Request request, IOException e) {
      }
      @Override
      public void onResponse(Response response) throws IOException {
        //NOT UI Thread
        if(response.isSuccessful()){
          System.out.println(response.code());
          System.out.println(response.body().string());
        }
      }
    });
  }

就是在同步的基础上讲execute改成enqueue,并且传入回调接口,但接口回调回来的代码是在非UI线程的,因此如果有更新UI的操作记得用Handler或者其他方式。
2、POST
说完GET该介绍些如何使用POST,POST情况下我们一般需要传入参数,甚至一些header,传入参数或者header
比如传入header

Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();

传入POST参数

RequestBody formBody = new FormEncodingBuilder()
  .add("platform", "android")
  .add("name", "bug")
  .add("subject", "XXXXXXXXXXXXXXX")
  .build();
  Request request = new Request.Builder()
   .url(url)
   .post(body)
   .build();

可以看出来,传入header或者post参数都是传到Request里面,因此最后的调用方式也和GET方式一样

Response response = client.newCall(request).execute();
  if (response.isSuccessful()) {
    return response.body().string();
  } else {
    throw new IOException("Unexpected code " + response);
  }

这个代码是同步网络请求,异步就改成enqueue就行了。

请求缓存
在网络请求中,缓存技术是一项应用比较广泛的技术,需要对请求过的网络资源进行缓存,而okhttp也支持这一技术,也使用十分方便,前文涨经常出现的OkHttpclient这个时候就要派送用场了。看下面代码

package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
  private final static String TAG = "TestActivity";
  private final OkHttpClient client = new OkHttpClient();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    File sdcache = getExternalCacheDir();
    int cacheSize = 10 * 1024 * 1024; // 10 MiB
    client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          execute();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();
  }
  public void execute() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response1 = client.newCall(request).execute();
    if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
    String response1Body = response1.body().string();
    System.out.println("Response 1 response:     " + response1);
    System.out.println("Response 1 cache response:  " + response1.cacheResponse());
    System.out.println("Response 1 network response: " + response1.networkResponse());
    Response response2 = client.newCall(request).execute();
    if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
    String response2Body = response2.body().string();
    System.out.println("Response 2 response:     " + response2);
    System.out.println("Response 2 cache response:  " + response2.cacheResponse());
    System.out.println("Response 2 network response: " + response2.networkResponse());
    System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));
  }
}

okhttpclient有点像Application的概念,统筹着整个okhttp的大功能,通过它设置缓存目录,我们执行上面的代码,得到的结果如下

response1 的结果在networkresponse,代表是从网络请求加载过来的,而response2的networkresponse 就为null,而cacheresponse有数据,因为我设置了缓存因此第二次请求时发现缓存里有就不再去走网络请求了。
但有时候即使在有缓存的情况下我们依然需要去后台请求最新的资源(比如资源更新了)这个时候可以使用强制走网络来要求必须请求网络数据

 public void execute() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response1 = client.newCall(request).execute();
    if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
    String response1Body = response1.body().string();
    System.out.println("Response 1 response:     " + response1);
    System.out.println("Response 1 cache response:  " + response1.cacheResponse());
    System.out.println("Response 1 network response: " + response1.networkResponse());
    request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
    Response response2 = client.newCall(request).execute();
    if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
    String response2Body = response2.body().string();
    System.out.println("Response 2 response:     " + response2);
    System.out.println("Response 2 cache response:  " + response2.cacheResponse());
    System.out.println("Response 2 network response: " + response2.networkResponse());
    System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));
  }

上面的代码中
response2对应的request变成

request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();

我们看看运行结果

response2的cache response为null,network response依然有数据。
同样的我们可以使用 FORCE_CACHE 强制只要使用缓存的数据,但如果请求必须从网络获取才有数据,但又使用了FORCE_CACHE 策略就会返回504错误,代码如下,我们去okhttpclient的缓存,并设置request为FORCE_CACHE

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    File sdcache = getExternalCacheDir();
    int cacheSize = 10 * 1024 * 1024; // 10 MiB
    //client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          execute();
        } catch (Exception e) {
          e.printStackTrace();
          System.out.println(e.getMessage().toString());
        }
      }
    }).start();
  }
  public void execute() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response1 = client.newCall(request).execute();
    if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
    String response1Body = response1.body().string();
    System.out.println("Response 1 response:     " + response1);
    System.out.println("Response 1 cache response:  " + response1.cacheResponse());
    System.out.println("Response 1 network response: " + response1.networkResponse());
    request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
    Response response2 = client.newCall(request).execute();
    if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
    String response2Body = response2.body().string();
    System.out.println("Response 2 response:     " + response2);
    System.out.println("Response 2 cache response:  " + response2.cacheResponse());
    System.out.println("Response 2 network response: " + response2.networkResponse());
    System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));
  }

取消操作
网络操作中,经常会使用到对请求的cancel操作,okhttp的也提供了这方面的接口,call的cancel操作。使用Call.cancel()可以立即停止掉一个正在执行的call。如果一个线程正在写请求或者读响应,将会引发IOException,同时可以通过Request.Builder.tag(Object tag)给请求设置一个标签,并使用OkHttpClient.cancel(Object tag)来取消所有带有这个tag的call。但如果该请求已经在做读写操作的时候,cancel是无法成功的,会抛出IOException异常。

public void canceltest() throws Exception {
    Request request = new Request.Builder()
        .url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
        .build();
    final long startNanos = System.nanoTime();
    final Call call = client.newCall(request);
    // Schedule a job to cancel the call in 1 second.
    executor.schedule(new Runnable() {
      @Override
      public void run() {
        System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f);
        call.cancel();
        System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f);
      }
    }, 1, TimeUnit.SECONDS);
    try {
      System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startNanos) / 1e9f);
      Response response = call.execute();
      System.out.printf("call is cancel:" + call.isCanceled() + "%n");
      System.out.printf("%.2f Call was expected to fail, but completed: %s%n",
          (System.nanoTime() - startNanos) / 1e9f, response);
    } catch (IOException e) {
      System.out.printf("%.2f Call failed as expected: %s%n",
          (System.nanoTime() - startNanos) / 1e9f, e);
    }
  }

成功取消

取消失败

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, okhttp
http
okhttp用法、okhttp3用法、okhttp的用法、okhttp3 详细讲解、okhttp3.5用法,以便于您获取更多的相关知识。

时间: 2024-10-26 20:19:09

Android使用OKHttp包处理HTTP相关操作的基本用法讲解_Android的相关文章

Android使用OKHttp包处理HTTP相关操作的基本用法讲解

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势.(GitHub页:https://github.com/square/okhttp) Android为我们提供了两种HTTP交互的方式:HttpURLConnection 和 Apache HTTP Client,虽然两者都支持HTTPS,流的上传和下载,配置超时,IPv6和连接池,已足够满足我们各种HTTP请求的需求.但更高效的使用HTTP 可

Android的OkHttp包中的HTTP拦截器Interceptor用法示例_Android

OkHttp(GitHub:https://github.com/square/okhttp) 的 Interceptor 就如同名称「拦截器」一样,拦截你的 Request 做一些你想做的事情再送出去.例如: 1.自动加上使用者目前使用的语言送出去取得对应语言的回传内容. 2.将 Request 计算出这个 Request 的 sigunature 再附加上送出去. 在 okHttp 中分成 Application Interceptor 和 Network Interceptor 两种. A

Android的OkHttp包中的HTTP拦截器Interceptor用法示例

OkHttp(GitHub:https://github.com/square/okhttp) 的 Interceptor 就如同名称「拦截器」一样,拦截你的 Request 做一些你想做的事情再送出去.例如: 1.自动加上使用者目前使用的语言送出去取得对应语言的回传内容. 2.将 Request 计算出这个 Request 的 sigunature 再附加上送出去. 在 okHttp 中分成 Application Interceptor 和 Network Interceptor 两种. A

详解Android的OkHttp包编写异步HTTP请求调用的方法_Android

OkHttp 除了支持常用的同步 HTTP 请求之外,还支持异步 HTTP 请求调用.在使用同步调用时,当前线程会被阻塞,直到 HTTP 请求完成.当同时发出多个 HTTP 请求时,同步调用的性能会比较差.这个时候通过异步调用可以提高整体的性能. 在通过 newCall 方法创建一个新的 Call 对象之后,不是通过 execute 方法来同步执行,而是通过 enqueue 方法来添加到执行队列中.在调用 enqueue 方法时需要提供一个 Callback 接口的实现.在 Callback 接

使用Android的OkHttp包实现基于HTTP协议的文件上传下载_Android

OkHttp的HTTP连接基础虽然在使用 OkHttp 发送 HTTP 请求时只需要提供 URL 即可,OkHttp 在实现中需要综合考虑 3 种不同的要素来确定与 HTTP 服务器之间实际建立的 HTTP 连接.这样做的目的是为了达到最佳的性能. 首先第一个考虑的要素是 URL 本身.URL 给出了要访问的资源的路径.比如 URL http://www.baidu.com 所对应的是百度首页的 HTTP 文档.在 URL 中比较重要的部分是访问时使用的模式,即 HTTP 还是 HTTPS.这会

Android的OkHttp包处理用户认证的代码实例分享_Android

OkHttp 提供了对用户认证的支持.当 HTTP 响应的状态代码是 401 时,OkHttp 会从设置的 Authenticator 对象中获取到新的 Request 对象并再次尝试发出请求.Authenticator 接口中的 authenticate 方法用来提供进行认证的 Request 对象,authenticateProxy 方法用来提供对代理服务器进行认证的 Request 对象. 用户认证的示例: OkHttpClient client = new OkHttpClient();

Android开发中编写蓝牙相关功能的核心代码讲解_Android

一. 什么是蓝牙(Bluetooth)?1.1  BuleTooth是目前使用最广泛的无线通信协议 1.2  主要针对短距离设备通讯(10m) 1.3  常用于连接耳机,鼠标和移动通讯设备等.二. 与蓝牙相关的API2.1 BluetoothAdapter: 代表了本地的蓝牙适配器 2.2 BluetoothDevice 代表了一个远程的Bluetooth设备三. 扫描已经配对的蓝牙设备(1)注:必须部署在真实手机上,模拟器无法实现 首先需要在AndroidManifest.xml 声明蓝牙权限

Android编程之Button控件配合Toast控件用法分析_Android

本文实例讲述了Android编程之Button控件配合Toast控件用法.分享给大家供大家参考,具体如下: 在本章教程中,我们将会学习Button控件的使用,同时顺便说一下Toast提示控件. 在Android程序开发中,我们使用最多的用户交互控件可能就是Button的了,而我们使用最多的事件估计也就是onclick事件了. 这些事件也是最简单的事件,我们一般通过google自带的API接口就可以调用了,我们具体看看怎么做吧. 第一步.新建一个工程Ep.Toast,活动和主视图名称我都使用默认的

详解Android的OkHttp包编写异步HTTP请求调用的方法

OkHttp 除了支持常用的同步 HTTP 请求之外,还支持异步 HTTP 请求调用.在使用同步调用时,当前线程会被阻塞,直到 HTTP 请求完成.当同时发出多个 HTTP 请求时,同步调用的性能会比较差.这个时候通过异步调用可以提高整体的性能. 在通过 newCall 方法创建一个新的 Call 对象之后,不是通过 execute 方法来同步执行,而是通过 enqueue 方法来添加到执行队列中.在调用 enqueue 方法时需要提供一个 Callback 接口的实现.在 Callback 接