zoukankan      html  css  js  c++  java
  • 第一篇:Retrofit主要类UML图

    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图,目的是为了更加深入的了解作者设计类的思路,比如作者是如何考虑一个类的功能、边界在哪里等。 

  • 相关阅读:
    哪个项目管理工具好用到哭?JIRA VS 华为软件开发云
    华为软件开发云CloudIDE功能简测
    移动APP云测试平台测评分析
    华为软件开发云对比Jenkins-JavaWeb项目持续部署方式
    微服务究竟该如何理解
    如何将Android Studio与华为软件开发云代码仓库无缝对接(二)
    如何将Android Studio与华为软件开发云代码仓库无缝对接(一)
    微服务,真的适合你么?
    如何更换git托管
    Redmine迁移至华为软件开发云-项目管理
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/5466928.html
Copyright © 2011-2022 走看看