Retrofit原理简析

May you return with a young heart after years of fighting.
愿你出走半生,归来仍是少年。​​​

Retrofit内部封装 OKHttp,采用注解的方式发起网络请求,同时融合 Rxjava,加入优雅的异步处理方式,使得其更加强大。

Retrofit的使用
定义接口

public interface BaiduService {

    @GET(".")
    Call<String> getBaidupage();

    @GET(".")
    Observable<String> getBaidu();
}

Retrofit请求

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.baidu.com")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
//动态代理的方法生成接口实现类
BaiduService baiduService = retrofit.create(BaiduService.class);
 //结合RxJava
Observable<String> baidu = baiduService.getBaidu();//创建Observable
baidu.subscribeOn(Schedulers.newThread())//子线程订阅访问网络
         .observeOn(AndroidSchedulers.mainThread())//主线程观察
         .subscribe(new BaseObserver<String>() {//产生订阅关系

             @Override
             public void onSuccess(String s) {
                 Log.e("Result", s);
             }

             @Override
             public void onFail(Throwable e) {
                 Log.e("Fail", e.getMessage());
             }

         });

Retrofit使用的关键一步就是Retrofit.create函数创建接口动态代理,查看源码

  public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
          }
        });
  }

关键的三步:
1 加载对应method的ServiceMethod实例

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);//是否有缓存
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);//同步代码块里是否有缓存
      if (result == null) {
      	//创建
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);//缓存起来
      }
    }
    return result;
  }

先去查看ServiceMethod是否有缓存,有的话直接取出,没有就创建,采用Builder模式,并用map缓存起来。

2 使用ServiceMethod实例和方法调用参数创建OkHttpCall
OkHttpCall是okhttp3.Call的一个包装类,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。

3 调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call或者Observable或其他自定义CallAdapter支持的返回)。
这里以Rxjava的Observable为例,源码:

@Override public Object adapt(Call<R> call) {
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return observable;
  }

RxJavaCallAdapterFactory创建的callAdapter在执行adapt时将OkHttpCall包装一个Rx的Observable,在Observable被subscribe时才会真正的执行http请求。

框架所用到的设计模式
A.建造者模式:Retrofit创建
B.工厂模式:addCallAdapterFactory
C.外观模式:内部封装OkHttp等
D.策略模式:adapt()不同对象不同策略方法实现
E.适配器模式:RxJavaCallAdapterFactory,Java8CallAdapterFactory,GuavaCallAdapterFactory
F.动态代理模式:create方法
G.观察者模式:RxJava

发布了28 篇原创文章 · 获赞 1 · 访问量 495

猜你喜欢

转载自blog.csdn.net/qq_40575302/article/details/104866004