2016-05-06 16:07:09

1.先上一张Retrofit的代码结构图:

可以看到,Retrofit自身的结构很简单,代码量也不是很大。红色框部分是一些注解类,就是一些标记。

简单的看一下客户端是如何使用Retrofit的:

定义接口:

 1 public interface WeatherDataService {
 2     @GET("/wtr-v2/temp/realtime")
 3     Call<MiWeatherData> getMiWeather(@Query("cityId") String cityId);
 4 
 5     @GET("/wtr-v2/temp/realtime")
 6     Observable<MiWeatherData> getMiWeatherObservable(@Query("cityId") String cityId);
 7 
 8     @GET("/wtr-v2/temp/realtime")
 9     MiWeatherData getMiWeatherCustomCallAdapter(@Query("cityId") String cityId);
10 }

客户端调用:

 1     private void getWeather() {
 2         retrofit = new Retrofit.Builder()
 3                 .baseUrl("http://weatherapi.market.xiaomi.com")
 4                 .addConverterFactory(GsonConverterFactory.create(gson))
 5                 .build();
 6         service = retrofit.create(WeatherDataService.class);
 7         Call<MiWeatherData> result = service.getMiWeather("101010100");
 8 
 9         try {
10             Response<MiWeatherData> r = result.execute();
11             MiWeatherData data = r.body();
12             Log.e("David", "ResponseBody data = " + data);
13             if (data != null) {
14                 Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.SD);
15                 Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.cityid);
16                 Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.WS);
17             }
18         } catch (IOException e) {
19             e.printStackTrace();
20         }
21     }

 

2. 几个主要类的UML简图:

2.1 Retrofit和Retrofit.Factory

Retrofit和ServiceMethod使用了Builder模式(省略了Director和Abstract Product的Builder模式)来构建自己,Retrofit的作用很简单,传入需要的参数,构建一个Retrofit对象,然后通过动态代理的方式,得到我们自定义的方法接口的实例,参数中除了baseUrl之外,其他都是可选的,如果没设置会使用默认值。

ServiceMethod就是我们自己调用的方法做一层封装而已,包括解析方法使用的注解、参数等,同时提供方法,生成网络请求需要的Request和解析请求结果。

 

2.1 CallAdapter和CallAdapter.Factory

CallAdapt的作用是把Call转变成你想要返回的对象,起作用的是adapt方法,CallAdapter.Factory的作用是获取CallAdapter。ExecutorCallAdapterFactory的CallAdapter会将回调方法放到主线程中执行,DefaultCallAdapterFactory不是。两者的CallAdapter能够接受的返回值类型为Call<T>。很明显,RxJavaCallAdapterFactory的CallAdapter能够接受的返回值是Oservable<T>。如果想让的方法直接返回一个对象,可以自定义一个CallAdapter.Factory。代码如下:

 1 private class MyCallAdapterFactory extends CallAdapter.Factory {
 2     @Override
 3     public CallAdapter<?> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) {
 4         return new CallAdapter<Object>() {
 5             @Override
 6             public Type responseType() {
 7                 return returnType;
 8             }
 9 
10             @Override
11             public <R> Object adapt(Call<R> call) {
12                 try {
13                     return call.execute().body();
14                 } catch (IOException e) {
15                     e.printStackTrace();
16                     return null;
17                 }
18             }
19         };
20     }
21 }

Service方法和CallAdapter的对应关系如下:

 

2.3 Converter和Converter.Factory

 

Converter的作用是将网络请求结果ResponseBody转换为我们希望的返回值类型。Converter.Factory的作用是获取Converter,这里很明显采用了静态工厂模式。如果你不设置ConverterFactory,那么调用WeatherDataInterface的三个方法都会崩溃,提示:Could not locate ResponseBody converter for class MiWeatherData。这是因为使用了默认的BuiltInConverters,而我们的方法不满足获取到responseBodyConverter的要求,所以崩溃,代码截图如下:

所以,如果不想设置Converter,那么我们的方法返回值必须为ResponseBody或者Void,如果是ResponseBody,且有@Streaming注解,会使用StreamingResponseBodyConverter,否则使用BufferingResponseBodyConveter。这两者基本都是原封不动的返回ResponseBody。而VoidResponseBodyConverter返回null~感觉这点比较坑,干点什么不好,非要返回null

Retrofit提供了多个Converter供选择,比如将Json转换为Object的GsonConverterFactory,如下图:

这也是Retrofit的一大特点---足够的开放、灵活。

 

2.4 OkHttpCall

OkHttpCall继承自interface Call,主要的作用是调起执行网络请求以及返回当前请求状态状态,但是真正的网络请求其实在okhttp3.Call接口,接口定义如下:

这个接口的实现类是okhttp3.RealCall,可以发现,Retrofit的Call接口和okhttp3的Call接口定义几乎是完全一样的,目的当然是实现OCP,这样做的好处显而易见:

1.利于扩展,retrofit2.Call接口可以有其他的实现类,不一定非要用OkHttp,只不过OkHttpCall用的恰好是OkHttp而已。

2.解耦,为了实现第一个目的,retrofit2.Call接口的存在就是理所当然的。

 

2.5 ParameterHandler

这是一个辅助类,用于解析我们自己定义的Method,由于我们是通过注解的方式来表达各种信息,比如请求类型(POST、GET)、Query参数、Body等,因此需要解析出来。不在主线,因此不作分析,但是里面的实现蛮复杂的,是个细致活儿。

 

2.6 RxJavaCallAdapterFactory分析

CallAdapterFactory的作用及工作机理前面已经介绍过了,RxJavaCallAdapterFactory的作用也是一样的,只不过RxJavaCallAdapterFactory中内部又定义了三种CallAdapter:ResponseCallAdapter、ResultCallAdapter和SimpleCallAdapter,根据返回值类型决定到底使用哪个,代码如下:

本质上处理流程是一致的,都是按照RxJava的套路执行请求并处理返回值的。

 

关于Retrofit中主要类的分解到此结束,之所以这么繁琐的画UML图,目的是为了更加深入的了解作者设计类的思路,比如作者是如何考虑一个类的功能、边界在哪里等。 

 posted on 2016-05-06 19:46  wlrhnh  阅读(1170)  评论(0编辑  收藏  举报