一、概述
Retrofit是Square公司開發的一個類型安全的Java和Android 的REST客戶端庫。來自官網的介紹:
A type-safe?HTTP client?for Android and Java
- Rest API是一種軟件設計風格,服務器作為資源存放地。客戶端去請求GET,PUT, POST,DELETE資源。并且是無狀態的,沒有session的參與。關于REST的介紹可以參考維基百科
- retrofit模型如下:(來自如何使用Retrofit寫一個Android的REST客戶端的小教程)
1)?POJO或模型實體類?: 從服務器獲取的JSON數據將被填充到這種類的實例中。
2)?接口?: 我們需要創建一個接口來管理像GET,POST...等請求的URL,這是一個服務類。
3)?RestAdapter類?: 這是一個REST客戶端(RestClient)類,retrofit中默認用的是Gson來解析JSON數據,你也可以設置自己的JSON解析器。
二、原理
在發起請求時,整個框架主要通過Call來封裝每一次的請求。
調用同步方法時,會使用應用線程來發送請求;
調用異步方法時會通過 OkHttp 的 Dispatcher 提供的線程來執行請求。
Dispatcher:Dispatcher內部實現了懶加載無邊界限制的線程池方式,同時該線程池采用了SynchronousQueue這種阻塞隊列。SynchronousQueue每個插入操作必須等待另一個線程的移除操作,同樣任何一個移除操作都等待另一個線程的插入操作。顯然這是一種快速傳遞元素的方式,也就是說在這種情況下元素總是以最快的方式從插入者(生產者)傳遞給移除者(消費者),這在多任務隊列中是最快處理任務的方式。
二、使用
添加依賴(gradle)或導jar包
添加依賴
在modul的build文件下的dependencies中添加
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
點擊Sync Now
(或)導jar包,點擊下載
retrofit-2.0.0-beta2.jar|????????????????Retrofit庫
converter-gson-2.0.0-beta2_.jar?| ?? Gson解析庫
gson-2.4.jar?????????????|????????????????????????Gson解析庫
okhttp-2.5.0.jar? ????????????|???????????????????Okhttp請求庫
okio-1.6.0.jar?????????????|???????????????????????Okhttp請求庫
說明:
Retrofit依賴于okhttp,所以需要集成okhttp
API返回的數據為JSON格式,在此我使用的是Gson對返回數據解析
添加權限
由于是網絡請求,需要在manifest中添加網絡請求的權限
<uses-permission android:name="android.permission.INTERNET"/>
創建實體類
這是使用Gson解析,需要創建一個POJO(Java對象)。服務器返回的JSON數據不能在Java里直接使用,所以我們需要用模型類來做轉換。這里使用jsonschema2pojo(需翻墻)來創建POJO。
得到JSON數據如下:
復制JSON字符串到輸入框中,填寫報名、類名,源代碼類型選擇JSON,注解類型選擇Gson,點擊Preview即可得到對應的POJO,如下圖
點擊preview,得到對應的實體類。將其拷貝到自己的工程中即可。
import?com.google.gson.annotations.SerializedName;
@Generated("org.jsonschema2pojo")
可刪除
POJO的轉換推薦使用GsonFormat,用法不就不說了,自己去搜吧。簡單易用
創建一個Retrofit?對象(核心用法一)
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create())//解析方法//這里建議:- Base URL: 總是以/結尾;- @Url: 不要以/開頭.baseUrl("http://www.wangyinews.com.cn/").build();
接口申明(核心用法二)
public interface NewsService {/*** 根據newsid獲取對應的資訊數據* 如果不需要轉換成Json數據,可以用了ResponseBody;* @param newsId* @return call*/@GET("News/{newsId}")Call<News> getNews(@Path("newsId") String newsId);
}
若需要重新定義接口地址可以使用@Url,例:
@GETCall<List<CaigenActivitySubjectsBean>> getActivitySubjectsList(@Url String url,@QueryMap Map<String, String> map);
更多請求方法請參考:Retrofit網絡請求Service,@Path、@Query、@QueryMap
- 創建訪問API的請求(核心用法三)
NewsService api = retrofit.create(NewsService .class);
Call<News> call = service.getNews("123456");
同步調用(核心用法四)
News news = call.execute();
異步調用(核心用法五)
call.enqueue(new?Callback<News>(){??@Override??public?void?onResponse(Response<News>?response)?{??//成功返回數據后在這里處理,使用response.body();獲取得到的結果News news = response.body();}??@Override??public?voidonFailure(Throwable?t)?{??//請求失敗在這里處理??}??});??
取消請求(核心用法六)
call.cancel();??
完成以上步驟就可以實現一個簡單的網絡請求了。
Tips:
當返回結果錯誤,調用response.errorBody().string();可以得到String類型的請求結果,但再次調用response.errorBody().string();得到的結果為""。具體原因不明