Retrofit的解析


Retrofit就是封装的okhttp,它关键使用了动态代理,注解,构建者模式,主线程的切换;

Retrofit网络框架的使用Demo

定义一个接口类

		public interface MyApi{
    
    
		
		    @GET("/user/name")
		    Call<ResponseBody> getUser();
		
		}

调用Retrofit

        //1.创建Retrofit    
		Retrofit retrofit = new Retrofit.Builder()
		      .baseUrl("https://api.example.com/")
		      .addConverterFactory(GsonConverterFactory.create())
		      .build();
        //2.生成RemoteService接口类
        MyApi api= retrofit.create(MyApi.class);
        //3.获取方法生成Call
        Call<ResponseBody> call = api.getUser();
        //4.调度请求
        call.enqueue(new Callback<ResponseBody>() {
    
    
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
    
    

            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
    
    

            }
        });

Retrofit中的动态代理模式

第2步中,MyApi api= retrofit.create(MyApi.class);其中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);
          }
        });
  }

源码中的Proxy.newProxyInstance方法使用的动态代理模式,不熟悉这个模式看一下这里代理模式–动态代理
第三步,Call < ResponseBody > call = api.getUser();调用之后,就相当于InvocationHandler调用invoke方法;
这个方法返回的类型是ExecutorCallbackCall类型;是Call的一个子类,具体为什么,很繁琐,没意义,就不分析了,不信你打印一下call的类型就只到了,说那是后面子线程切换到主线程就会用到它,很关键;

Retrofit中的注解解析(涉及构建者模式,主要看它build()方法)

主要是解析MyApi类下面的方法信息

InvocationHandler类的invoke方法

         @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.
   				// 省略无用代码	
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
          }

loadServiceMethod(method)方法

		  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;
		  }

new ServiceMethod.Builder<>(this, method).build()方法

在这里可以看到对MyApi中方法getUser的解析,这里是方法很长,只截取关键代码

      for (Annotation annotation : methodAnnotations) {
    
    
        parseMethodAnnotation(annotation);
      }

子线程到主线程的切换过程

看代码第4步, call.enqueue(new Callback< ResponseBody >() {}
上面说过了call的类型是ExecutorCallbackCall,我们直接在这个类中看它的enqueue方法就可以

     @Override public void enqueue(final Callback<T> callback) {
    
    
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback<T>() {
    
    
        @Override public void onResponse(Call<T> call, final Response<T> response) {
    
    
          callbackExecutor.execute(new Runnable() {
    
    
            @Override public void run() {
    
    
              if (delegate.isCanceled()) {
    
    
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
    
    
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
    
    
          callbackExecutor.execute(new Runnable() {
    
    
            @Override public void run() {
    
    
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

看代码,那个onResponse方法的回调中有一个callbackExecutor,这个是什么?

  static class Android extends Platform {
    
    
    @Override public Executor defaultCallbackExecutor() {
    
    
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    
    
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
    
    
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
    
    
        handler.post(r);
      }
    }
  }

它就是在这里生成的MainThreadExecutor,他关联的是主线程的Loop.getMainLooper();
在第一步Retrofit初始化里面有调用

    public Retrofit build() {
    
    
      if (baseUrl == null) {
    
    
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
    
    
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
    
    
        callbackExecutor = platform.defaultCallbackExecutor();
      }

所以Retrofit在OKhttp返回数据以后,立刻就切换到了主线程,当然Retrofit源码还要有很多值得分析的,弄得太多很容易陷入代码不能自拔,我这里是从几个关键点切入写的有点简单,方便阅读!

猜你喜欢

转载自blog.csdn.net/eyishion/article/details/103617907