Android网络请求:OkHttp实战

android网络请求是个耗时的操作,一定要在子线程中运行,添加网络权限,目前有很多流行的网络框架。比如okhttp,volley,xutils等等。今天主要介绍okhttp的使用,后续分享给多,比如socket网络请求,文件上传下载。

一,HTTP协议的主要特点

HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
详见原文:HTTP协议详解(真的很经典)

二,OKHttp介绍

An HTTP & HTTP/2 client for Android and Java applications. For more information see the website and the wiki.前往OkHttp官网
使用okhttp很简单,它的请求/响应 API设计,运用了流利的builder,确保方式多样而又固定,支持异步请求和回调。它支持android 2.3或以上,jdk版本要求不低于1.7。

okhttp的主要特点:

  1. HTTP/2支持共享一个socket,发送多个请求给相同的主机。
  2. 连接池减少了请求的潜在因素。
  3. 明显的GZIP压缩下载大小。
  4. 响应缓存避免网络重复请求。

确保所有的网络请求只有一个OkHttpClient实例,可以用单例模式。也可以如下:

  public static OkHttpClient okHttpClient = new OkHttpClient();

okhttp发送请求,封装的方法,必须在子线程运行。另外回调方法是在子线程中,要更新UI必须在主线程,自己处理。下面的方法中的OkHttpClient实例统一用上面生成的。

三,okhttp发送get请求

演示基本的用法,不懂的地方可以github下载源码研究。

//OKHTTP GET
    public static String get(String url){
        Request request = new Request.Builder().url(url).build();
        Response response = null;
        try {
            response =  new OkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new IOException("Unexpected code " + response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
       return "";
    }

四,OKHttp构建RequestBody

发送post的请求,比较普遍。无论有一个参数,多个参数,或者文件上传,都可以构建特定的RequestBody发送请求。

1.发送一个键值对。

RequestBody requestBody = RequestBody.create(MediaType.parse("UTF-8"),"param=value");

2.发送多个参数,构建表单一样的请求参数。

RequestBody requestBody = new FormBody.Builder()
                .add("param1", "value1")
                .add("param12", "value2")
                .build();

3. post json字符串

MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, json);

4. 文件上传

MediaType,文件类型标示,通常”application/octet-stream”就可以,比如jpg图片,可以MediaType.parse(“image/jpg”)。表单参数根据项目需要自行调整。

final MediaType mediaType = MediaType.parse("application/octet-stream");
            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data"));
            builder.addFormDataPart("description", description);
            builder.addFormDataPart("file", fileName, RequestBody.create(mediaType, uploadFile));
   //构建请求体
  RequestBody requestBody = builder.build();

五,发送的post请求的方法

 //使用Request的post方法来提交请求体RequestBody
    public static String post(String url, RequestBody requestBody) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

六,Headers相关。

先看官方对header和addHeader两种方法的解释:

   /**
     * Sets the header named {@code name} to {@code value}. If this request already has any headers
     * with that name, they are all replaced.
     */
    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }

    /**
     * Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued
     * headers like "Cookie".
     *
     * 

Note that for some headers including {@code Content-Length} and {@code Content-Encoding}, * OkHttp may replace {@code value} with a header derived from the request body. */ public Builder addHeader(String name, String value) { headers.add(name, value); return this; }

意思就是说,header是给已有的请求头设置一个值,
addHeader是添加新的请求头,value的值可以有多个(以英文”,”分开)。例如:

private final OkHttpClient client = new OkHttpClient();

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

  Response response = client.newCall(request).execute();
  if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    LogUtils.debug("Server:"+response.header("Server"));
    LogUtils.debug("Date: " + response.header("Date"));
    LogUtils.debug("Vary: " + response.headers("Vary"));
}

返回结果:

Server: GitHub.com
Sat, 30 Apr 2016 01:24:48 GMT
Vary: [Accept, Accept-Encoding]

七,总结

okhttp是目前比较流行的网络框架,开源项目,本文介绍了本人一些常用的用法,不到之处望留言指出。对比了一些网络框架,还是挺赞的。
有时间再研究研究源码,未完待续,欢迎交流,杜乾,Dusan,Q 291902259。

你可能感兴趣的:(Android,Base,OpenDeveloper)