天天看點

Android REST Clients 實踐-官方實作

Android程式中REST Clients是一個很常見的使用場景,不過一些書籍介紹的都是很入門的網絡通路,離在程式實際使用的場景還差的很遠,今天我大概介紹一下自己的實踐經驗

網絡通路

要作REST Client網絡通路時第一步,一般認為2.3之前用Apache HttpClient,2.3之後使用HttpURLConnection具體原因參見這裡,因為無論是HttpClient和HttpURLConnection書中都有介紹,此處就不展開了。

不過實際使用中HttpURLConnection還是很繁瑣的,我一般在需要網絡請求的地方會采用OkHttp,此處引用一下OkHttp官網的一段GET請求代碼大家看看

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}
           

異步請求

雖然有了網絡請求的代碼,但是在Android中是不允許在ui線程進行網絡請求的,官方的解決方法有兩個

1. 建立一個Work Thread進行網絡請求,請求結束之後使用Handler再切換到UI線程繼續結果處理。具體實作參見這裡

2. 使用AsyncTask

AsyncTask寫起來很簡單,一般大家都會采用AsyncTask。兩個方案也都有無數實作示例,此處聊一些需要注意的點

1. AsyncTask其實可以看做Work Thread+Handler的封裝

2. AsyncTask一個示例隻能執行一次,是以如果有重複背景任務-》前台任務這種切換場景的話Work Thread+Handler是更好的選擇。

3. AsyncTask本身存在一些缺陷,另外各版本AsyncTask實作也有些差異使用時需要注意AsyncTask中的線程池的政策是否滿足你目前的情景

4. 一般使用Handler的時候會用匿名類實作,使用AsyncTask的時候會使用内部類。這兩個常見的場景都容易造成記憶體洩漏,使用時需注意。

5. AsyncTask或者Work Thread + Handler的方案實際使用中需考慮Activity LifeCycle變化,這塊内容後續會詳細讨論

序列化

RESTFul接口一般會傳回json結果,使用HttpURLConnection讀到的是json 字元串。我們一般使用的是資料對象,此時我們要将讀到的字元串序列化為合适的對象。最常見的解決方案就是Google的Gson,此處引用部分文檔代碼大家看一下

class BagOfPrimitives {
  private int value1 = ;
  private String value2 = "abc";
  private transient int value3 = ;
  BagOfPrimitives() {
    // no-args constructor
  }
}

(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  
==> json is {"value1":,"value2":"abc"}

Note that you can not serialize objects with circular references since that will result in infinite recursion. 

(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);   
==> obj2 is just like obj
           

總結

至此異步網絡請求并序列化為對象的官方方案都讨論完了,但是在實踐中大家都不這麼幹……是以你也沒看到實際的示例代碼,下一篇咱們讨論一下在實踐中大家的實作方案。

繼續閱讀