OkHttp 基础(1)

OkHttp 官网

官网地址 : http://square.github.io/okhttp

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

1 基础介绍

OkHttp 是一款优秀的开源 HTTP 框架 , 支持Android 2.3 及其以上版本 , 主要功能如下 :

  • GET 请求
  • POST 请求
  • 基于 HTTP 的文件 上传和下载
  • 图片加载
  • 下载文件的 GZIP 压缩 节省带宽
  • 响应缓存 避免重复的网络请求
  • 使用连接池来降低响应延迟问题

2 使用准备

Android Studio 使用方式

在项目 Modulebuild.gradle 文件中增加如下代码,然后 Sync project 成功后即可使用.

compile 'com.squareup.okhttp3:okhttp:3.5.0'

注意增加网络访问权限在AndroidManifest.xml文件中

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

3 基本使用

3.1 GET 请求

/**
 * OkHttp Get请求测试方法.
 * @param url  URL 地址.
 * @return
 *      返回数据.
 * @throws IOException
 */
public String okHttp_get(String url)throws IOException{
    // 1. 创建HTTP Client 对象.尽量使用全局的避免过多创建该对象
    OkHttpClient client = new OkHttpClient();
    // 2. 创建请求对象 .
    Request request = new Request.Builder()
            .url(url)
            .build();
    // 3. 执行请求,获取请求响应对象.
    Response response = client.newCall(request).execute();
    // 4. 处理结果
    if (response.isSuccessful()){
        // 请求成功
        Log.d(TAG,"请求成功.");
        return response.body().string();
    }else {
        Log.e(TAG,"请求失败!");
        return null;
    }
}

3.2 POST 请求

// 数据类型.
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
/**
 * OkHttp POST 请求.
 * @param url   URL地址
 * @param json  JSON 格式数据
 * @return
 *      响应数据
 * @throws IOException
 */
public String OkHttp_post(String url,String json)throws IOException{
    // 1. 创建Client对象
    OkHttpClient client = new OkHttpClient();
    // 2. 创建POST请求体
    RequestBody requestBody = RequestBody.create(JSON,json);
    // 3. 创建 请求对象.
    Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();
    // 4. 发送请求 , 创建响应对象
    Response response = client.newCall(request).execute();
    // 5. 处理结果
    if (response.isSuccessful()){
        // 成功
        Log.d(TAG,"请求成功.");
        return response.body().string();
    }else {
        // 失败
        Log.e(TAG,"请求失败!");
        return null;
    }
}

3.3 带键值对的POST

/**
 * 带键值的 POST请求
 * @param url   URL地址
 * @return
 *      响应数据字符串.
 * @throws IOException
 */
public String OkHttp_post_key(String url)throws IOException{
    // 1. 创建对象.
    OkHttpClient client = new OkHttpClient();
    // 2. 创建请求体.
    FormBody.Builder builder = new FormBody.Builder();
    builder.add("name","WSJ")
            .add("sex","male")
            .add("age","22");
    FormBody formBody = builder.build();
    Request request = new Request.Builder()
            .url(url)
            .post(formBody)
            .build();
    // 3. 发送请求.
    Response response = client.newCall(request).execute();
    // 4. 处理响应
    if (response.isSuccessful()){
        Log.d(TAG,"请求成功.");
        return response.body().string();
    }else {
        Log.e(TAG,"请求失败!");
        return response.body().string();
    }
}

4 OkHttp 相关类介绍.

4.1 OkHttpClient 类

请求工厂类, 它可以用来发送 HTTP 请求, 读取请求响应.

使用 OkHttpClient 类时应该公用一个实例对象, 因为每一个 OkHttpClient 实例对象保持着他们自己的连接池和线程池,重用连接和线程将会节省电量和内存,因此如果为每一次网络请求都创建一个OkHttpClient对象就会造成资源浪费

(1) 创建OkHttpClient对象的两种方式

方式一 :使用默认配置 new OkHttpClient()

// 创建一个单例 客户端 .
public final OkHttpClient client = new OkHttpClient();

方式二 :自定义配置 new OkHttpClient.Builder()

// The singleton HTTP client.
public final OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor())
    .cache(new Cache(cacheDir, cacheSize))
    .build();

使用 newBuilder() 可以自定义一个OkHttpClient实例对象. 创建出来的client同样是共享连接池和线程池以及配置信息.可以使用 builder 的相关方法创建出指定功能的client对象.

// 500ms超时.
OkHttpClient eagerClient = client.newBuilder()
       .readTimeout(500, TimeUnit.MILLISECONDS)
       .build();
Response response = eagerClient.newCall(request).execute();

(2) 资源释放问题

OkHttpClient 所保持的连接处于空闲状态时, OkHttpClient 会自动将这些连接占用的资源释放掉. 因此不需要我们主动去释放.如果想在程序中主动强制释放这些资源,可以进行如下操作 :

第一步 : shutdown() 方法将 dispatcher's executor服务关闭.

// 关闭服务.
client.dispatcher().executorService().shutdown();

第二步 : evictAll() 清空连接池,

注意 : 连接池的守护线程不会立即退出.

// 清空连接池
client.connectionPool().evictAll();

第三步 : close() 关闭缓存(如果有).

注意 :如果关闭了缓存则不能创建 Call 否则会出错.

// 关闭缓存
client.cache().close();

(3) 常用方法

// 创建新的 Call 对象, 准备发送请求.
public Call newCall(Request request);

4.2 Request 类

HTTP 请求类,如果该类的 body 是null 或者他本身是不可变的那么该实例对象是不可变的.

(1) 内部类 Request.Builder

该类可以用来创建 Request 对象. 就像组装机器一样构造一个实例对象.

// 构造方法
public Builder();
// 设置目标 URL 方法
public Request.Builder url(HttpUrl url);
public Request.Builder url(String url);
public Request.Builder url(URL url);
// 设置/修改 HTTP 请求头信息
public Request.Builder header(String name,String value);
// 增加一个请求头.Prefer this method for multiply-valued headers like "Cookie".
public Request.Builder addHeader(String name,String value);
// 删除请求头指定信息
public Request.Builder removeHeader(String name);
// 使用参数中的请求头信息替换原来的请求头.
public Request.Builder headers(Headers headers);
// 设置缓存策略
public Request.Builder cacheControl(CacheControl cacheControl);

// get 请求
public Request.Builder get();
// head 请求
public Request.Builder head();
// POST 请求
public Request.Builder post(RequestBody body);
// delete 请求
public Request.Builder delete(RequestBody body);
public Request.Builder delete();
// 设置请求
public Request.Builder method(String method,RequestBody body);
// 设置 请求 TAG,可以在取消请求时使用.如果TAG为空或者未设置,则他本事就是TAG.
public Request.Builder tag(Object tag);

(1) 其他方法

// 获取请求体数据对象.
public RequestBody body();
// Builder对象.
public Request.Builder newBuilder();
// 缓存策略.
public CacheControl cacheControl();
// 是否是 HTTPS
public boolean isHttps();
// 获取制定文件头信息.
public String header(String name);
// 获取请求头
public Headers headers();
public List<String> headers(String name);
// 请求方法
public String method();
// URL 地址.
public HttpUrl url();

4.3 RequestBody 类

请求体类.

// 构造方法.
public RequestBody();
// 返回将要发送的数据,如果不知道就返回 -1;
public long contentLength() throws IOException;
// 返回一个新的请求数据体对象,如果 `contentType` 非空,并且未指定编码格式则默认为 `UTF-8`
public static RequestBody create(MediaType contentType,String content);
public static RequestBody create(MediaType contentType,okio.ByteString content);
public static RequestBody create(MediaType contentType,byte[] content);
// 分段上传.
public static RequestBody create(MediaType contentType,
                                 byte[] content,
                                 int offset,
                                 int byteCount);
// 可以实现文件上传
public static RequestBody create(MediaType contentType,File file);

4.4 Response 类

请求响应对象. 使用完成后需要关闭.

// 获取响应数据 , 使用之后必须关闭
public ResponseBody body();
// HTTP 请求响应代码
public int code();
// Returns true if the code is in [200..300), 
// which means the request was successfully received, understood, and accepted.
public boolean isSuccessful();
// HTTP 状态信息
public String message();

4.5 ResponseBody 类

响应数据对象. 使用后一定要 关闭 .

ResponseResponseBody 类都需要关闭.如果关闭了 Response 则就会默认关闭它的ResponseBody.
关闭阻塞式

 Call call = client.newCall(request);
   try (Response response = call.execute()) {
     ... // Use the response.
   }

关闭异步请求

  Call call = client.newCall(request);
   call.enqueue(new Callback() {
     public void onResponse(Call call, Response response) throws IOException {
       try (ResponseBody responseBody = response.body()) {
         ... // Use the response.
       }
     }
     public void onFailure(Call call, IOException e) {
       ... // Handle the failure.
     }
   });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容