OkHttp各种请求方法

原文地址:http://blog.csdn.net/liyuchong2537631/article/details/48369403


支持 SPDY ,共享同一个 Socket 来处理同一个服务器的所有请求

  1. 如果 SPDY 不可用,则通过连接池来减少请求延时

  2. 无缝的支持GZIP来减少数据流量

  3. 缓存响应数据来减少重复的网络请求


  OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。


  OkHttp是一个相对成熟的解决方案,据说Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。




一、测试使用我们的OKHttp第三方库

1.第一步我们需要去创建一个 OKHttpClient 对象

OkHttpClient okHttpClient = new OkHttpClient();

 

2.下一步我们还需要一个 Request 对象,她可以已如下方式被创建

Request request = new Request.Builder()
                                    .url(requestUrl)
                                    .build(); 

requestUrl是一个字符串变量代表这个URL是为了JSON请求(The requestUrl is a String variable representing the Url for the JSON request.) 

在这个测试中,我们将会使用如下的URl:http://iheartquotes.com/api/v1/random?format=json

 

3.再下一步我们需要实例化一个 Call 对象

Call call  = okHttpClient.newCall(request);

 

Call对象会取走我们的 okHttpClient对象 和 我们的 request对象。

 

4.在实例化Call对象后,我们现在可以 Execute(执行)她。Executing一个Call后将会返回一个 Response,并且会抛出一个 IOException的异常,这就是为什么们会用一个try,catch块包裹她。

复制代码
try{
        Response response = call.execute();
}catch (IOException e){
        e.printStackTrace();
}
复制代码

 

 

5.执行完我们的Call后,我们需要通过使用 response.isSuccessful()来检查Call对象是否执行成功,

通过response.isSuccessful()的返回值为true或者是false来判断。

这我们仅仅是一个测试,如果Call成功的话,我们将会通过Log来打印我们的response。

复制代码
try{
        Response response = call.execute();
        if(response.isSuccessful()){
                //The call was successful.print it to the log
                Log.v("OKHttp",response.body().string());
        }
    }catch(IOException e){
        e.printStackTrace();
}
复制代码

 

 

6.测试Code!

这是新手一个常见的错误。在Android中不允许任何网络的交互在主线程中进行。It disallows it to force developers to use asynchronous callbacks.(能力有限这句话不敢强译)。但是现在,我们的代码看起来看起来十分的号好!下面我们来看看如何修复这个问题。

 

7.Fix issue

为了修补这个问题,我们只需要让我们的Call执行在非主线程内,所以利用一个 asynchronous callback(异步的callBack)

让我们call异步的方法是通过调用我们Call对象的 enqueue()方法。

复制代码
call.enqueue(new Callback()) {
        
        @Override
        public void onFailure( Request request, IOException e ) {
        
        }
        
        @Override
        public void OnResponse( Response response) throws IOException {
                try {
                        if(response.isSuccessful()){
                            //The call was successful. print it to the log
                            log.v("OKHttp",response.body.string());
                         }
                }catch (IOException e) {
                    e.printStackTrace();
                }
        }
});
复制代码

 

 

8.在我们再次执行我们的code之前,我们还需要再改一改。如果我们想要现在执行她,我们可能还会接收到错误的提示,因为我们应用的程序没有得到相应的相应的网络权限。所以我们需要再AndroidManifest.xml中添加应用权限。

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

 

 

9.当我们执行完code后,我们将接受到如下的log输出:

 

10.This means, we are now able to execute asynchronous network calls and use the data inside the callback method, when it is ready!

 

onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()

看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等




二、请求方法介绍

1、HTTP请求方法

  • 同步GET请求

[java]  view plain  copy
  1. private final OkHttpClient client = new OkHttpClient();  
  2.   
  3. public void run() throws Exception {  
  4.     Request request = new Request.Builder()  
  5.             .url("http://publicobject.com/helloworld.txt")  
  6.             .build();  
  7.     Response response = client.newCall(request).execute();  
  8.     if (!response.isSuccessful())  
  9.         throw new IOException("Unexpected code " + response);  
  10.     Headers responseHeaders = response.headers();  
  11.     for (int i = 0; i < responseHeaders.size(); i++) {  
  12.         System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));  
  13.     }  
  14.     System.out.println(response.body().string());  
  15. }  

  Response类的string()方法会把文档的所有内容加载到内存,适用于小文档,对应大于1M的文档,应   使用流()的方式获取。

[java]  view plain  copy
  1. response.body().byteStream()  
  • 异步GET请求

[java]  view plain  copy
  1. private final OkHttpClient client = new OkHttpClient();  
  2.   
  3. public void run() throws Exception {  
  4.     Request request = new Request.Builder()  
  5.             .url("http://publicobject.com/helloworld.txt")  
  6.             .build();  
  7.     client.newCall(request).enqueue(new Callback() {  
  8.         @Override  
  9.         public void onFailure(Request request, IOException e) {  
  10.             e.printStackTrace();  
  11.         }  
  12.   
  13.         @Override  
  14.         public void onResponse(Response response) throws IOException {  
  15.             if (!response.isSuccessful()) {  
  16.                 throw new IOException("Unexpected code " + response);  
  17.             }  
  18.             Headers responseHeaders = response.headers();  
  19.             for (int i = 0; i < responseHeaders.size(); i++) {  
  20.                 System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));  
  21.             }  
  22.   
  23.             System.out.println(response.body().string());  
  24.         }  
  25.     });  
  26. }  

  读取响应会阻塞当前线程,所以发起请求是在主线程,回调的内容在非主线程中。

  • POST方式提交字符串

[java]  view plain  copy
  1. private static final MediaType MEDIA_TYPE_MARKDOWN  
  2.         = MediaType.parse("text/x-markdown; charset=utf-8");  
  3.   
  4. private final OkHttpClient client = new OkHttpClient();  
  5.   
  6. public void run() throws Exception {  
  7.     String postBody = ""  
  8.             + "Releases\n"  
  9.             + "--------\n"  
  10.             + "\n"  
  11.             + " * _1.0_ May 6, 2013\n"  
  12.             + " * _1.1_ June 15, 2013\n"  
  13.             + " * _1.2_ August 11, 2013\n";  
  14.   
  15.     Request request = new Request.Builder()  
  16.             .url("https://api.github.com/markdown/raw")  
  17.             .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))  
  18.             .build();  
  19.   
  20.     Response response = client.newCall(request).execute();  
  21.     if (!response.isSuccessful())   
  22.         throw new IOException("Unexpected code " + response);  
  23.   
  24.     System.out.println(response.body().string());  
  25. }  

  因为整个请求体都在内存中,应避免提交1M以上的文件。

  • POST方式提交流

[java]  view plain  copy
  1. private final OkHttpClient client = new OkHttpClient();  
  2.   
  3. public void run() throws Exception {  
  4.     RequestBody requestBody = new RequestBody() {  
  5.         @Override  
  6.         public MediaType contentType() {  
  7.             return MEDIA_TYPE_MARKDOWN;  
  8.         }  
  9.   
  10.         @Override  
  11.         public void writeTo(BufferedSink sink) throws IOException {  
  12.             sink.writeUtf8("Numbers\n");  
  13.             sink.writeUtf8("-------\n");  
  14.             for (int i = 2; i <= 997; i++) {  
  15.                 sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i)));  
  16.             }  
  17.         }  
  18.   
  19.         private String factor(int n) {  
  20.             for (int i = 2; i < n; i++) {  
  21.                 int x = n / i;  
  22.                 if (x * i == n) return factor(x) + " × " + i;  
  23.             }  
  24.             return Integer.toString(n);  
  25.         }  
  26.     };  
  27.   
  28.     Request request = new Request.Builder()  
  29.             .url("https://api.github.com/markdown/raw")  
  30.             .post(requestBody)  
  31.             .build();  
  32.   
  33.     Response response = client.newCall(request).execute();  
  34.     if (!response.isSuccessful())   
  35.         throw new IOException("Unexpected code " + response);  
  36.   
  37.     System.out.println(response.body().string());  
  38. }  

  使用Okio框架以流的形式将内容写入,这种方式不会出现内存溢出问题。

  • POST方式提交文件

[java]  view plain  copy
  1. public static final MediaType MEDIA_TYPE_MARKDOWN  
  2.         = MediaType.parse("text/x-markdown; charset=utf-8");  
  3.   
  4. private final OkHttpClient client = new OkHttpClient();  
  5.   
  6. public void run() throws Exception {  
  7.     File file = new File("README.md");  
  8.   
  9.     Request request = new Request.Builder()  
  10.             .url("https://api.github.com/markdown/raw")  
  11.             .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))  
  12.             .build();  
  13.   
  14.     Response response = client.newCall(request).execute();  
  15.     if (!response.isSuccessful())   
  16.         throw new IOException("Unexpected code " + response);  
  17.   
  18.     System.out.println(response.body().string());  
  19. }  
  • POST方式提交表单

[java]  view plain  copy
  1. private final OkHttpClient client = new OkHttpClient();  
  2.   
  3. public void run() throws Exception {  
  4.     RequestBody formBody = new FormEncodingBuilder()  
  5.             .add("search""Jurassic Park")  
  6.             .build();  
  7.     Request request = new Request.Builder()  
  8.             .url("https://en.wikipedia.org/w/index.php")  
  9.             .post(formBody)  
  10.             .build();  
  11.   
  12.     Response response = client.newCall(request).execute();  
  13.     if (!response.isSuccessful())   
  14.         throw new IOException("Unexpected code " + response);  
  15.   
  16.     System.out.println(response.body().string());  
  17. }  

  表单的每个Names-Values都进行了URL编码。如果服务器端接口未进行URL编码,可定制个  FormBuilder。

  • 文件上传(兼容html文件上传)

[java]  view plain  copy
  1. private static final String IMGUR_CLIENT_ID = "...";  
  2. private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");  
  3.   
  4. private final OkHttpClient client = new OkHttpClient();  
  5.   
  6. public void run() throws Exception {  
  7.     // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image  
  8.     RequestBody requestBody = new MultipartBuilder()  
  9.             .type(MultipartBuilder.FORM)  
  10.             .addPart(  
  11.                     Headers.of("Content-Disposition""form-data; name=\"title\""),  
  12.                     RequestBody.create(null"Square Logo"))  
  13.             .addPart(  
  14.                     Headers.of("Content-Disposition""form-data; name=\"image\""),  
  15.                     RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))  
  16.             .build();  
  17.   
  18.     Request request = new Request.Builder()  
  19.             .header("Authorization""Client-ID " + IMGUR_CLIENT_ID)  
  20.             .url("https://api.imgur.com/3/image")  
  21.             .post(requestBody)  
  22.             .build();  
  23.   
  24.     Response response = client.newCall(request).execute();  
  25.     if (!response.isSuccessful())   
  26.         throw new IOException("Unexpected code " + response);  
  27.     System.out.println(response.body().string());  
  28. }  
  原文地址:

1、http://www.cnblogs.com/ryan-ys/p/4777450.html

2、http://www.mamicode.com/info-detail-511504.html


你可能感兴趣的:(Android开发,okhttp,okhttp异步请求)