Android——使用OkHttp(含各种请求方法)

支持 SPDY ,共享同一个 Socket 来处理同一个服务器的所有请求
1、如果 SPDY 不可用,则通过连接池来减少请求延时
2、无缝的支持GZIP来减少数据流量
3、缓存响应数据来减少重复的网络请求

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()

二、请求方法介绍

1、HTTP请求方法

  • 同步GET请求
private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    Request request = new Request.Builder()  
            .url("http://publicobject.com/helloworld.txt")  
            .build();  
    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())  
        throw new IOException("Unexpected code " + response);  
    Headers responseHeaders = response.headers();  
    for (int i = 0; i < responseHeaders.size(); i++) {  
        System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));  
    }  
    System.out.println(response.body().string());  
}  

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

  • 异步GET请求
private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    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) {  
            e.printStackTrace();  
        }  

        @Override  
        public void onResponse(Response response) throws IOException {  
            if (!response.isSuccessful()) {  
                throw new IOException("Unexpected code " + response);  
            }  
            Headers responseHeaders = response.headers();  
            for (int i = 0; i < responseHeaders.size(); i++) {  
                System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));  
            }  

            System.out.println(response.body().string());  
        }  
    });  
}  

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

  • POST方式提交字符串
private static final MediaType MEDIA_TYPE_MARKDOWN  
        = MediaType.parse("text/x-markdown; charset=utf-8");  

private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    String postBody = ""  
            + "Releases\n"  
            + "--------\n"  
            + "\n"  
            + " * _1.0_ May 6, 2013\n"  
            + " * _1.1_ June 15, 2013\n"  
            + " * _1.2_ August 11, 2013\n";  

    Request request = new Request.Builder()  
            .url("https://api.github.com/markdown/raw")  
            .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))  
            .build();  

    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())   
        throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  
}  

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

  • POST方式提交流
private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    RequestBody requestBody = new RequestBody() {  
        @Override  
        public MediaType contentType() {  
            return MEDIA_TYPE_MARKDOWN;  
        }  

        @Override  
        public void writeTo(BufferedSink sink) throws IOException {  
            sink.writeUtf8("Numbers\n");  
            sink.writeUtf8("-------\n");  
            for (int i = 2; i <= 997; i++) {  
                sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i)));  
            }  
        }  

        private String factor(int n) {  
            for (int i = 2; i < n; i++) {  
                int x = n / i;  
                if (x * i == n) return factor(x) + " × " + i;  
            }  
            return Integer.toString(n);  
        }  
    };  

    Request request = new Request.Builder()  
            .url("https://api.github.com/markdown/raw")  
            .post(requestBody)  
            .build();  

    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())   
        throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  
}  

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

  • POST方式提交文件
public static final MediaType MEDIA_TYPE_MARKDOWN  
        = MediaType.parse("text/x-markdown; charset=utf-8");  

private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    File file = new File("README.md");  

    Request request = new Request.Builder()  
            .url("https://api.github.com/markdown/raw")  
            .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))  
            .build();  

    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())   
        throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  
}  
  • POST方式提交表单
private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    RequestBody formBody = new FormEncodingBuilder()  
            .add("search", "Jurassic Park")  
            .build();  
    Request request = new Request.Builder()  
            .url("https://en.wikipedia.org/w/index.php")  
            .post(formBody)  
            .build();  

    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())   
        throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  
}  

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

  • 文件上传(兼容html文件上传)
private static final String IMGUR_CLIENT_ID = "...";  
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");  

private final OkHttpClient client = new OkHttpClient();  

public void run() throws Exception {  
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image  
    RequestBody requestBody = new MultipartBuilder()  
            .type(MultipartBuilder.FORM)  
            .addPart(  
                    Headers.of("Content-Disposition", "form-data; name=\"title\""),  
                    RequestBody.create(null, "Square Logo"))  
            .addPart(  
                    Headers.of("Content-Disposition", "form-data; name=\"image\""),  
                    RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))  
            .build();  

    Request request = new Request.Builder()  
            .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)  
            .url("https://api.imgur.com/3/image")  
            .post(requestBody)  
            .build();  

    Response response = client.newCall(request).execute();  
    if (!response.isSuccessful())   
        throw new IOException("Unexpected code " + response);  
    System.out.println(response.body().string());  
}  

参考文献
http://blog.csdn.net/liyuchong2537631/article/details/48369403

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Android使用OkHttp发送WebSocket请求的示例代码: ```java import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; import okio.ByteString; public class WebSocketClient extends WebSocketListener { private OkHttpClient client; private WebSocket webSocket; public WebSocketClient() { client = new OkHttpClient(); } public void start() { Request request = new Request.Builder().url("wss://your.websocket.url").build(); webSocket = client.newWebSocket(request, this); } @Override public void onOpen(WebSocket webSocket, Response response) { super.onOpen(webSocket, response); // 连接成功 webSocket.send("Hello, WebSocket!"); } @Override public void onMessage(WebSocket webSocket, String text) { super.onMessage(webSocket, text); // 收到消息 } @Override public void onMessage(WebSocket webSocket, ByteString bytes) { super.onMessage(webSocket, bytes); // 收到二进制消息 } @Override public void onClosing(WebSocket webSocket, int code, String reason) { super.onClosing(webSocket, code, reason); // 正在关闭连接 } @Override public void onClosed(WebSocket webSocket, int code, String reason) { super.onClosed(webSocket, code, reason); // 连接已关闭 } @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { super.onFailure(webSocket, t, response); // 连接失败 } } ``` 使用方法: ```java WebSocketClient client = new WebSocketClient(); client.start(); ``` 注意:需要在AndroidManifest.xml中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值