欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解

 更新時間:2016年07月13日 10:11:27   作者:chenzujie  
這篇文章主要介紹了Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解,包括操作如何利用OKHttp操作HTTP請求與處理緩存等內(nèi)容,需要的朋友可以參考下

OKHttp是一款高效的HTTP客戶端,支持連接同一地址的鏈接共享同一個socket,通過連接池來減小響應(yīng)延遲,還有透明的GZIP壓縮,請求緩存等優(yōu)勢。(GitHub頁:https://github.com/square/okhttp)

Android為我們提供了兩種HTTP交互的方式:HttpURLConnection 和 Apache HTTP Client,雖然兩者都支持HTTPS,流的上傳和下載,配置超時,IPv6和連接池,已足夠滿足我們各種HTTP請求的需求。但更高效的使用HTTP 可以讓您的應(yīng)用運行更快、更節(jié)省流量。而OkHttp庫就是為此而生。
OkHttp是一個高效的HTTP庫:

  • 支持 SPDY ,共享同一個Socket來處理同一個服務(wù)器的所有請求
  • 如果SPDY不可用,則通過連接池來減少請求延時
  • 無縫的支持GZIP來減少數(shù)據(jù)流量
  • 緩存響應(yīng)數(shù)據(jù)來減少重復(fù)的網(wǎng)絡(luò)請求
  • 會從很多常用的連接問題中自動恢復(fù)。

如果您的服務(wù)器配置了多個IP地址,當(dāng)?shù)谝粋€IP連接失敗的時候,OkHttp會自動嘗試下一個IP。OkHttp還處理了代理服務(wù)器問題和SSL握手失敗問題。
使用 OkHttp 無需重寫您程序中的網(wǎng)絡(luò)代碼。OkHttp實現(xiàn)了幾乎和java.net.HttpURLConnection一樣的API。如果您用了 Apache HttpClient,則OkHttp也提供了一個對應(yīng)的okhttp-apache 模塊。


引入
可以通過下載jar包直接導(dǎo)入工程地址
或者通過構(gòu)建的方式導(dǎo)入
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'

用法
在向網(wǎng)絡(luò)發(fā)起請求的時候,我們最常用的就是GET和POST,下面就來看看如何使用
1. GET
在OKHttp,每次網(wǎng)絡(luò)請求就是一個Request,我們在Request里填寫我們需要的url,header等其他參數(shù),再通過Request構(gòu)造出Call,Call內(nèi)部去請求參數(shù),得到回復(fù),并將結(jié)果告訴調(diào)用者。
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執(zhí)行得到Response,通過Response可以得到code,message等信息。
這個是通過同步的方式去操作網(wǎng)絡(luò)請求,而android本身是不允許在UI線程做網(wǎng)絡(luò)請求操作的,因此我們需要自己開啟一個線程。
當(dāng)然,OKHttp也支持異步線程并且有回調(diào)返回,有了上面同步的基礎(chǔ),異步只要稍加改動即可
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());
        }
      }
    });
  }
就是在同步的基礎(chǔ)上講execute改成enqueue,并且傳入回調(diào)接口,但接口回調(diào)回來的代碼是在非UI線程的,因此如果有更新UI的操作記得用Handler或者其他方式。
2、POST
說完GET該介紹些如何使用POST,POST情況下我們一般需要傳入?yún)?shù),甚至一些header,傳入?yún)?shù)或者h(yuǎn)eader
比如傳入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參數(shù)
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參數(shù)都是傳到Request里面,因此最后的調(diào)用方式也和GET方式一樣
Response response = client.newCall(request).execute();
  if (response.isSuccessful()) {
    return response.body().string();
  } else {
    throw new IOException("Unexpected code " + response);
  }
這個代碼是同步網(wǎng)絡(luò)請求,異步就改成enqueue就行了。

請求緩存
在網(wǎng)絡(luò)請求中,緩存技術(shù)是一項應(yīng)用比較廣泛的技術(shù),需要對請求過的網(wǎng)絡(luò)資源進(jìn)行緩存,而okhttp也支持這一技術(shù),也使用十分方便,前文漲經(jīng)常出現(xiàn)的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的概念,統(tǒng)籌著整個okhttp的大功能,通過它設(shè)置緩存目錄,我們執(zhí)行上面的代碼,得到的結(jié)果如下
201671395230108.jpg (848×127)
response1 的結(jié)果在networkresponse,代表是從網(wǎng)絡(luò)請求加載過來的,而response2的networkresponse 就為null,而cacheresponse有數(shù)據(jù),因為我設(shè)置了緩存因此第二次請求時發(fā)現(xiàn)緩存里有就不再去走網(wǎng)絡(luò)請求了。
但有時候即使在有緩存的情況下我們依然需要去后臺請求最新的資源(比如資源更新了)這個時候可以使用強制走網(wǎng)絡(luò)來要求必須請求網(wǎng)絡(luò)數(shù)據(jù)
 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對應(yīng)的request變成
request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
我們看看運行結(jié)果
201671395608033.jpg (853×142)
response2的cache response為null,network response依然有數(shù)據(jù)。
同樣的我們可以使用 FORCE_CACHE 強制只要使用緩存的數(shù)據(jù),但如果請求必須從網(wǎng)絡(luò)獲取才有數(shù)據(jù),但又使用了FORCE_CACHE 策略就會返回504錯誤,代碼如下,我們?nèi)khttpclient的緩存,并設(shè)置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));
  }
201671395741595.jpg (882×84)
取消操作
網(wǎng)絡(luò)操作中,經(jīng)常會使用到對請求的cancel操作,okhttp的也提供了這方面的接口,call的cancel操作。使用Call.cancel()可以立即停止掉一個正在執(zhí)行的call。如果一個線程正在寫請求或者讀響應(yīng),將會引發(fā)IOException,同時可以通過Request.Builder.tag(Object tag)給請求設(shè)置一個標(biāo)簽,并使用OkHttpClient.cancel(Object tag)來取消所有帶有這個tag的call。但如果該請求已經(jīng)在做讀寫操作的時候,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);
    }
  }
成功取消
2016713100051268.jpg (613×103)
取消失敗
2016713100130237.jpg (867×102)

相關(guān)文章

  • Android中CheckBox復(fù)選框控件使用方法詳解

    Android中CheckBox復(fù)選框控件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Android中CheckBox復(fù)選框控件的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android組件之間交互核心Intent用法分析

    Android組件之間交互核心Intent用法分析

    這篇文章主要介紹了Android組件之間交互核心Intent用法,結(jié)合實例形式分析了Intent實現(xiàn)組件之間交互的步驟與相關(guān)技巧,需要的朋友可以參考下
    2016-06-06
  • Android使用URLConnection提交請求的實現(xiàn)

    Android使用URLConnection提交請求的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了Android使用URLConnection提交請求的實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SharedPreference 初始化源碼解析

    SharedPreference 初始化源碼解析

    這篇文章主要為大家介紹了SharedPreference 初始化源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Android應(yīng)用中clearFocus方法調(diào)用無效的問題解決

    Android應(yīng)用中clearFocus方法調(diào)用無效的問題解決

    clearFocus()主要用于清除EditText的焦點,Android App開發(fā)中很多時候會發(fā)現(xiàn)其調(diào)用無效,帶著這個問題我們就來看一下本文主題、Android應(yīng)用中clearFocus方法調(diào)用無效的問題解決
    2016-05-05
  • Android中GridView插件的使用方法

    Android中GridView插件的使用方法

    今天小編就為大家分享一篇關(guān)于Android中GridView插件的使用方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Android之OOM異常解決案例講解

    Android之OOM異常解決案例講解

    這篇文章主要介紹了Android之OOM異常解決案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Android DatePicker和DatePickerDialog基本用法示例

    Android DatePicker和DatePickerDialog基本用法示例

    這篇文章主要介紹了Android DatePicker和DatePickerDialog基本用法,實例分析了DatePicker和DatePickerDialog控件針對手機時間設(shè)置的相關(guān)技巧,需要的朋友可以參考下
    2016-06-06
  • Android手勢ImageView三部曲 第一部

    Android手勢ImageView三部曲 第一部

    這篇文章主要為大家詳細(xì)介紹了Android手勢ImageView三部曲的第一部,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android設(shè)計模式系列之組合模式

    Android設(shè)計模式系列之組合模式

    這篇文章主要介紹了Android設(shè)計模式系列之組合模式的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09

最新評論