Retrofit與okhttp都是Square公司出品,retrofit就是在okhttp的基礎(chǔ)上做了一層封裝。網(wǎng)絡請求相關(guān)操作交給Okhttp處理,我們只需要通過簡單的配置就能使用retrofit來進行網(wǎng)絡請求了。

Retrofit使用入門
首先創(chuàng)建一個接口:
public interface UserService {
@GET("users/{user}/lessons")
Call<List<Lesson>> listLessons(@Path("user") String user);
}
這個接口是為了通過一個url獲取用戶課程列表的接口,當然看著這個url地址好像也不是一個完整的能夠使用的url地址,確實是這樣的,Retrofit請求的地址是由兩部分組成的,一部分是后面要介紹的Retrofit對象中的baseUrl和類似上面接口中的path地址共同構(gòu)成的。
接下來我們是不是要定義一個實現(xiàn)該接口的類呢 ? 當然不是的啦。我們接下來要做的是只需構(gòu)造一個Retrofit對象即可,至于原理,后面會說到。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.test.com/")
.build();
UserService service = retrofit.create(UserService.class);
Call<List<Lesson>> lessonCall = service.listLessons("test");
Response<List<Lesson>> result = null;
//同步調(diào)用
result = lessonCall.execute();
//異步調(diào)用
lessonCall.enqueue(new Callback<List<Lesson>>() {
@Override
public void onResponse(Call<List<Lesson>> call, Response<List<Lesson>> response) {
result = response.body();
}
@Override
public void onFailure(Call<List<Lesson>> call, Throwable t) {
t.printStackTrace();
}
});
這樣就能輕易的調(diào)用http請求了,當然了,這只是一個小小的簡單的demo,Retrofit的功能不止這些。
Retrofit使用更上一層樓
前面我們弄了一個很基本的一個例子,下面我們將更進一步使用Retrofit更多的功能。
請求類型: 我們都知道http的請求類型有GET,POST,DELETE,PUT,HEAD,PATCH 這些類型,而與之相對應的,Retrofit也包含了相對應的注解給予支持,@GET,@POST,@DELETE,@PUT,@HEAD,@PATCH 使用對應的注解即可。
請求參數(shù):
-
@Query && @QueryMap:@Query用于http請求的單個query參數(shù)傳遞;@QueryMap用于多個參數(shù)傳遞,鍵值對。 -
@Field && @FieldMap:@Field用于post請求的單個參數(shù)傳遞;@FieldMap用于post請求多個參數(shù)傳遞。 -
@Header && @HeaderMap:@Header用于單個請求頭參數(shù);@HeaderMap用于多個請求頭參數(shù)傳遞。 -
@Part && @PartMap:@Part用于單個文件的上傳;@PartMap用于多個文件上傳。 -
@Path:用于path路徑變量的傳遞接收。
上述示例代碼:
@GET("users/{user}/lessons")
Call<List<Lesson>> listLessons(@Path("user") String user);
@GET("users/getuser")
Call<User> getUser(@Query("userId")String userId);
@GET("users/getUserByCondition")
Call<List<User>> getUserByCondition(@QueryMap Map<String,String> conditionMap);
@POST("users/authorization")
Call<User> authorization(@HeaderMap Map headerMap);
@Multipart//當有文件需要上傳時加入
@POST("users/add")
Call<User> addUser(@FieldMap Map userInfo, @Part("photo")MultipartBody.Part file);
上面這些示例都是可以直接返回對應的結(jié)果類型,但如果我們想做一個通用的Retrofit封裝的http請求工具類,那就只好返回最原始的string類型,畢竟不同請求返回結(jié)果類型不同,像這樣:
public interface CommonHttpService{
@GET
Call<String> getHttpRequest(@Url String url, @HeaderMap Map<String,String> headerMap, @QueryMap Map<String,String> queryMap);
@FormUrlEncoded
@POST
Call<String> postHttpRequest(@Url String url, @HeaderMap Map<String,String> headerMap, @QueryMap Map<String,String> queryMap, @FieldMap Map<String,String> formMap);
@POST
Call<String> postHttpRequest(@Url String url, @HeaderMap Map<String,String> headerMap, @QueryMap Map<String,String> queryMap, @Body String body);
}
你會發(fā)現(xiàn)與前面的有些許不同,首先呢,@POST或@GET后面沒有跟上一部分path路徑了,而是改由參數(shù)中的@Url String url在調(diào)用方法時傳入,增加了靈活性。
Converter
如果僅僅是這樣是返回不了對應的結(jié)果類型的,需要用到converter,converter的作用就是將RequestBody或ResponseBody轉(zhuǎn)換為我們需要的類型,例如前面的我們想要使請求返回String類型還需要加上依賴:
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-scalars</artifactId>
<version>LATEST</version>
</dependency>
然后在構(gòu)造Retrofit對象時,加上ScalarsConverterFactory的配置:
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://api.test.com")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
ScalarsConverterFactory里面包含了對ResponseBody進行String,原始數(shù)據(jù)類型及其包裝類的轉(zhuǎn)換。
目前,Retrofit已經(jīng)有了幾個官方的converter:
//uses Gson for serialization to and from JSON
Gson: com.squareup.retrofit2:converter-gson
//uses Jackson for serialization to and from JSON
Jackson: com.squareup.retrofit2:converter-jackson
//uses Moshi for serialization to and from JSON
Moshi: com.squareup.retrofit2:converter-moshi
//A Converter which uses Protocol Buffer binary serialization
Protobuf: com.squareup.retrofit2:converter-protobuf
//A Converter which uses Wire for protocol buffer-compatible serialization.
Wire: com.squareup.retrofit2:converter-wire
//A Converter which uses Simple for XML serialization.
Simple XML: com.squareup.retrofit2:converter-simplexml
//A Converter which supports converting strings and both primitives and their boxed types to text/plain bodies.
Scalars : com.squareup.retrofit2:converter-scalars
這些converter已經(jīng)能基本滿足我們?nèi)粘5男枰?,但凡事有例外,比如我們要加密解密,要改寫結(jié)果等,所以這時候就需要我們自己來寫converter.我們以自定義一個 String Converter作為一個例子:
-
自定義converter:
先定義一個converter factory:
public class CustomStringConverterFactory extends Converter.Factory {
public static CustomStringConverterFactory create() {
return new CustomStringConverterFactory();
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
if (type == String.class) {
return new CustomStringConverter();
}
return null;
}
}
這里我們只是將ResponseBody進行轉(zhuǎn)換,如果你同時要將RequestBody進行轉(zhuǎn)換,那就同時要覆寫public Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit)方法.
定義Converter,轉(zhuǎn)換的邏輯在這里面進行:
public class CustomStringConverter implements Converter<ResponseBody, String> {
@Override
public String convert(ResponseBody value) throws IOException {
return value.string();
}
}
最后一步就是將converterfactory加入到Retrofit對象構(gòu)造中使用:
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://api.test.com") .addConverterFactory(CustomStringConverterFactory.create())
.build();
好了,這樣就能愉快的使用你自己定義的converter了,這里需要注意的是你如果添加的converter有多個的話小心順序。