開新坑辣!一直以爲本身框架了解的特別少,大多隻知其名而不知實現原理,然而幾乎每次面試都會被問及框架。因此頗有必要總結一些經常使用的框架,但願本身能堅持把這個『框架學習』系列的新坑填的厚實一點!android
1.概述git
a.Retrofit是Square公司推出的一個基於RESTful風格的HTTP網絡框架。github
相關連接地址:面試
b.與OkHttp的關係:設計模式
是對OkHttp網絡請求框架的二次封裝,本質還是OkHttp。即網絡請求的工做本質上是由OkHttp完成,而Retrofit僅負責網絡請求接口的封裝。流程如圖:bash
- App應用程序經過Retrofit請求網絡,其實是使用Retrofit接口層封裝請求參數、Header、Url等信息,以後由OkHttp完成後續的請求操做。
- 在服務端返回數據以後,OkHttp將原始的結果交給Retrofit,Retrofit會根據用戶的需求對結果進行解析。
- 經過使用大量的設計模式進行功能模塊的解耦,使得上面的過程進行得更加簡單和流暢。
c.其餘網絡框架簡介:服務器
相比於上述兩種網絡框架,Retrofit具備的優勢:網絡
- 遵循Restful API設計風格,簡潔易用
- 支持同步&異步網絡請求
- 支持多種數據的解析&序列化格式(Gson、 Json、XML、 Protobuf)
- 支持對RxJava支持
- 註解化配置高度解耦、採用大量設計模式簡化使用
2.使用方式app
大體分紅八個步驟:框架
step1:添加Retrofit庫、OkHttp庫、數據解析器集成庫的依賴,並註冊網絡權限
在app文件包下的build.gradle中添加依賴,這裏用的是JSON數據解析器:
compile 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.4.0'
複製代碼
在AndroidManifest.xml中註冊權限:
<uses-permission android:name="android.permission.INTERNET"/>
複製代碼
step2:建立接收服務器返回數據的類
請求後服務器會返回數據,須要根據返回數據的格式和解析方式(Json、XML等)來定義實體類Model。
假設有返回數據格式爲以下JSON,其中,若是用戶名和密碼匹配成功,則code值爲1,反之爲0:
{
"code":1,
"data":{
"id":10001,
"username":"Tom",
"email":"888888888@qq.com",
"tel":"18088888888"
},
"message":"success"
}
複製代碼
則對應的實體類UserInfoModel:
public class UserInfoModel {
public int code;
public UserInfo data;
public String message;
public static class UserInfo{
public int id;
public String username;
public String email;
public String tel;
}
}
複製代碼
step3:建立用於描述網絡請求的接口
定義一個網絡請求的接口,接口函數裏要定義URL路徑、請求參數、返回類型。其中,須要使用註解來描述請求類型和請求參數。
public interface Interface {
@GET("URL")
Call<Model> getCall(@Query("xxx") String xxx);
// 用@GET("URL")聲明瞭URL路徑
// 用getCall()接收網絡請求數據,並用註解@Query("xxx") 聲明瞭請求參數
// 該方法會返回一個Retrofit的Call對象,這裏聲明瞭這個對象處理的數據類型爲自定義Model
}
複製代碼
在上例中,對應的UserMgrService接口以下,當發送請求參數爲Tom和123456時,請求將發送給的URL爲『login?username=Tom&pwd=123456』,並會返回以前定義的GSON數據:
public interface UserMgrService{
@GET("login")
Call<UserInfoModel> login(@Query("username") String username,@Query("pwd") String pwd);
}
複製代碼
經常使用的註解含義如圖:
這裏能夠發現,@GET和@Query搭配使用,@POST和@Field搭配使用。
step4:建立Retrofit對象並設置數據解析器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("URL") //設置網絡請求的Url地址,注意以要以斜線(表明根目錄)結尾
.addConverterFactory(GsonConverterFactory.create()) //設置數據解析器,這裏表示用的是JSON解析返回值
.build();
複製代碼
經常使用的數據解析器如圖:
step5:生成接口對象
因爲是interface不是class,沒法直接調用內部方法,須要利用已建立的Retrofit對象去生成代理的接口對象。
UserMgrService service=retrofit.create(UserMgrService.class);
複製代碼
step6:調用接口方法返回Call對象
調用接口對象的方法,返回一個能夠執行網絡訪問的網絡工做對象。
Call<UserInfoModel> call=service.login("Tom","123456");
複製代碼
step7:發送網絡請求(異步 / 同步)
a.同步:調用Call對象execute()
,返回結果是響應體。
//開線程進行網絡請求
new Thread(new Runable()){
@Override
pubblic void run(){
Response<UserInfoModel> response=null;
try{
response=call.execute();
}catch{
e.printStackTrace();
}
//處理服務器返回的數據
}
}.start();
複製代碼
b.異步:調用Call對象enqueue()
,參數是一個回調。
//異步時,框架中已經封裝好數據轉換、線程切換的操做,無需手動開線程
call.enqueue(new CallBack<UserInfoModel>(){
@Override
public void onResponse(Call<UserInfoModel> call,Response<UserInfoModel> response){
//處理服務器返回的數據
}
@Override
public void onFailure(Call<UserInfoModel> call,Throwable t){
}
});
複製代碼
step8: 處理服務器返回的數據
如今能夠去打印出返回結果:
Log.i("response","code:"+response.body().code);//結果爲"code:1"
複製代碼
下面給出官方給的simple demo,便於更好的理解Retrofit的使用步驟:
//step3:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
public static void main(String... args) throws IOException {
// step4:Create a very simple REST adapter which points the GitHub API.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
// step5:Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.class);
// step6:Create a call instance for looking up Retrofit contributors.
Call<List<Contributor>> call = github.contributors("square", "retrofit");
// step7:Fetch and print a list of the contributors to the library.
List<Contributor> contributors = call.execute().body();
//step8:
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
複製代碼
實例:這是一份很詳細的 Retrofit 2.0 使用教程(含實例講解)
以上,能夠看到,Retrofit可根據不一樣的接口定義,靈活地生成對應的網絡工做對象,而後利用這個對象去訪問網絡。它就像一個工廠,只提供產品,自己不處理網絡請求,而是讓產品去處理網絡請求。
下一篇將進行Retrofit的源碼分析~