Retrofit自定義ConverterFactory
有時候我們用Retrofit需要在收到請求后處理response,當然寫在RXJava的回調中也是可以的。
但是如果需要處理的耗時比較長UI線程就會卡住,或者需要重復使用這一段處理(例如解密參數)時代碼就會很亂。
為了解決這個問題,我們可以自定義一個ConverterFactory
使用方法如下(第4行)
#!JAVA
private static Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl("https://acharts.co/")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(RankConverterFactory.create())
.build();
這個是接口,記住這個泛型List,后面會用到
#!JAVA
@GET("/uk_singles_top_75")
Observable<List> getUK();
我們需要繼承Converter.Factory抽象類,並且按照需求實現它的方法。
比如我們想要處理response,則重寫responseBodyConverter方法,讓它返回一個Converter(用於處理response的類),也就是說,在Factory中只是判斷是否處理,如果處理的話就提供相應的Converter。處理response發生在Coverter中。
我們這里只需要處理response,所以只重寫了responseBodyConverter
下面是代碼
#!JAVA
public class RankConverterFactory extends Converter.Factory {
//工廠方法,用於創建實例
public static RankConverterFactory create() {
return new RankConverterFactory();
}
//response返回到本地后會被調用,這里先判斷是否要攔截處理,不攔截則返回null
//判斷是否處理的依據就是type參數,type就是上面接口出現的List了
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (type == List.class) {
return new RankBodyConverter<Type>();
}
//如果返回null則不處理,交給別的Converter處理
return null;
}
// 一個Converter類,T就是上面接口中的List了
private static class RankBodyConverter<T> implements Converter<ResponseBody, T> {
RankBodyConverter() {
}
//在這個方法中處理response
@Override
public T convert(ResponseBody value) throws IOException {
String body = value.string();
return (T) ResponseUtil.handleRankResponse(body);
}
}
}
可能看到這么多泛型會暈。不要着急,這些泛型用來干什么的呢?讓我們理一理
由於一個Retrofit實例可以添加多個ConverterFactory,那么他如何判斷是否由這個ConverterFactory處理呢?
答案就是判斷通過接口的泛型(上面送List),在responseBodyConverter方法中,
首先判斷接口中的泛型是否為List類型,type == List.class
如果是就返回相應的Converter表示處理response,如果不是就返回null交給別的ConverterFactory處理。
