接上篇Retrofit的简单解析,这篇写个最简单的CallAdapter跟Converter的例子。
接口找了个免费的天气接口
首先是Converter,上篇文章后面我们知道GsonConverterFactory是cover到了所有的responseType,我们自定义的写了两种:String和Weather,Weather是我自定义的数据bean。
首先看调用:
public class RetrofitFactory {
static Retrofit retrofit;
static ApiService apiService;
public static ApiService getInstance() {
//https://restapi.amap.com/v3/weather/weatherInfo?key=5326a9f59587393b549f3cffefa0459b&city=110000&output=json&extensions=base
if (apiService == null) {
retrofit = new Retrofit.Builder()
.addConverterFactory(new MyConverterFactory())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(new MyCallAdapterFactory())
.baseUrl("https://restapi.amap.com/v3/weather/")
.build();
apiService = retrofit.create(ApiService.class);
}
return apiService;
}
}
public class TestRetrofit {
public static void test() {
retrofitGetWeather();
}
public static void retrofitGetWeather() {
Call<Weather> call = RetrofitFactory.getInstance().getWeather("5326a9f59587393b549f3cffefa0459b", "110000", "json", "base");
call.enqueue(new Callback<Weather>() {
@Override
public void onResponse(Call<Weather> call, Response<Weather> response) {
LogUtil.Companion.d("" + response.body().toString());
}
@Override
public void onFailure(Call<Weather> call, Throwable t) {
}
});
}
MyConverterFactory:
public class MyConverterFactory extends Converter.Factory {
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (type == String.class) {
return new StringConverter();
} else if (type == Weather.class) {
return new WeatherConverter();
}
return null;
}
class StringConverter implements Converter<ResponseBody, String> {
@Nullable
@Override
public String convert(ResponseBody value) throws IOException {
return value.string();
}
}
class WeatherConverter implements Converter<ResponseBody, Weather> {
@Nullable
@Override
public Weather convert(ResponseBody value) throws IOException {
Weather weather = new Weather();
weather.setCount(100);
weather.setStatus(999);
weather.setInfo("I'm A Fake Weather create by MyConverterFactory!");
Exception e = new Exception("this is a exception log for print");
e.printStackTrace();
return weather;
}
}
上面的代码我们可以看到,首先判断了类型,我只管String和Weather类型,其他类型都返回null,返回null表示这个类型我处理不了,retrofit会继续找下一个factory去处理,这个自定义converter其实是把结果请求下来,并创建了一个假的Weather返回给了调用者。这个Weather就是我们调用的时候需要返回的Weather,就是上面这里要返回的Weather
Call<Weather> call = RetrofitFactory.getInstance().getWeather("5326a9f59587393b549f3cffefa0459b", "110000", "json", "base");
MyCallAdapterFactory:
public class MyCallAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
for (Annotation a : annotations) {
LogUtil.Companion.d("Annotation->" + a.toString());
}
Type wrapperType = getParameterUpperBound(0, (ParameterizedType) returnType);
LogUtil.Companion.d("MyCallAdapterFactory->" + returnType
+ " getRawType->" + getRawType(returnType)
+ " Type->" + wrapperType);
if (wrapperType == String.class) {
return new StringCallAdapter();
} else if (wrapperType == Weather.class) {
Exception e = new Exception("call Weather print");
e.printStackTrace();
return new WeatherCallAdapter();
}
return null;
}
class StringCallAdapter implements CallAdapter<String, String> {
@Override
public Type responseType() {
return String.class;
}
@Override
public String adapt(Call<String> call) {
try {
return call.execute().body();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
class WeatherCallAdapter implements CallAdapter<String, retrofit2.Call> {
@Override
public Type responseType() {
return Weather.class;
}
@Override
public retrofit2.Call adapt(Call<String> call) {
LogUtil.Companion.d("yocn weather->" + call.request().toString());
return call;
}
}
其实这个CallAdapter里面什么都没有做,只是做了个打印,进来的Call原样子返回了回去。其实就是类似Retrofit里面的DefaultCallAdapterFactory,它也是什么斗殴没有做,直接把Call返回了回去。
要注意的是getRawType方法跟getParameterUpperBound方法,看打印可以看到retrofit2.Call<retrofit.Weather>
getRawType拿到的是retrofit2.Call
getParameterUpperBound返回的是retrofit.Weather
我们需要判断是不是Weather
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return call;
}
};
}
}
可以执行的例子Github传送门
网友评论