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处理。