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