Retrofit简要分析


Retrofit是对网络请求实现了一套请求架构封装,屏蔽底层网络实现,使网络请求像调用自己的接口一样,首先看一下使用

public interface GitHubService {//定义request方法以及返回需要的response类型
		  @GET("users/{user}/repos")
		  List<Repo> listRepos(@Path("user") String user);
		  @GET("users/{user}/repos")
		  Call<List<Repo>> listRepos2(@Path("user") String user,Callback<List<Repo>> calback);
	}
	
	void usetest(){
		static final String BASE_URL = "http://yourwebsite/services/";
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())//Response转换器,这里以GsonConvert为例
                        .addCallAdapterFactory(Java8CallAdapterFactory.create())//request处理Adapter
                        .build();

		GitHubService service = retrofit.create(GitHubService.class);
		List<Repo> data =null;
		
		// 直接调用
		data = service.listRepos("user1");
		 
		// 异步callback方式
		service.listRepos2("user2",new Callback<List<Repo>>() {

			@Override
			public void onResponse(Call<List<Repo>> call,
					Response<List<Repo>> response) {
				data=response.body();
			}

			@Override
			public void onFailure(Call<List<Repo>> call, Throwable t) {
				// TODO Auto-generated method stub
				Log.e("error",t.getMessage());
			}
		            
		 });
	}

官方介绍:http://square.github.io/retrofit/#api-declaration


具体看一下内部是怎么调用实现:首先从create开始

 public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);//校验service接口定义是否合法
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },//产生代理,实现对service接口调用
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, Object... args)
              throws Throwable {
            ...
         //每个接口最终转换为ServiceMethod,存储在serviceMethodCache中
          ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
         //网络访问与okhttp结合生成OkHttpCall
           OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
        //发起请求,返回结果,解析返回
           return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

这里的OkHttpCall是Retrofit对自身Call接口实现,并不是okhttp3里的对象,通过实现接口内部封装okhttp3.Call,当然也可以替换其它网络库

看看call接口

public interface Call<T> extends Cloneable {
  ...
  Response<T> execute() throws IOException;
...
  void enqueue(Callback<T> callback);
...
  boolean isExecuted();
...
  void cancel();
...
  boolean isCanceled();
...
  Call<T> clone();

  /** The original HTTP request. */
  Request request();
}

与okhttp里面call类似,只不过自身重新定义一下,降低耦合度

看看Okhttp3大体实现

final class OkHttpCall<T> implements Call<T> {
  private final ServiceMethod<T, ?> serviceMethod;
  private final Object[] args;

  private volatile boolean canceled;

  // All guarded by this.
  private okhttp3.Call rawCall;
  private Throwable creationFailure; // Either a RuntimeException or IOException.
  private boolean executed;

  OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }
......
  @Override public void enqueue(final Callback<T> callback) {//异步请求
    if (callback == null) throw new NullPointerException("callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;
...
    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }

    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
          throws IOException {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);//解析response
        } catch (Throwable e) {
          callFailure(e);
          return;
        }
        callSuccess(response);
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callSuccess(Response<T> response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }

  @Override public Response<T> execute() throws IOException {//同步调用请求
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
          throw (IOException) creationFailure;
        } else {
          throw (RuntimeException) creationFailure;
        }
      }

      call = rawCall;
      if (call == null) {
        try {
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException e) {
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }

    return parseResponse(call.execute());//执行请求并解析
  }

  private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }

    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
      T body = serviceMethod.toResponse(catchingBody);//调用指定的Convert对response进行泛型转换
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }
convert最终调用来源Retrofit里的在builder里加入Converter.Factory

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
      Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
      }
    }

 public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

看看GsonResponseBodyConverter实现

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
  private final Gson gson;
  private final TypeAdapter<T> adapter;

  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override public T convert(ResponseBody value) throws IOException {//通过TypeAdapter转换为对应实体类型T
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      return adapter.read(jsonReader);
    } finally {
      value.close();
    }
  }
}

整理一下,Retrofit使用Jdk里的Proxy动态代理方式实现对接口方法调用,即当调用接口方法listRepos时,调用了Proxy中的invoke,将对应接口方法及注解封装为ServiceMethod对象,通过CallAdapter对OkHttpCall调用获取Response并将数据转换为T返回给调用者
Retrofit中build构建方法:

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

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {//检测网络请求client,如果没有指定则创建一个client
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {//回调执行callback的线程,如果没有指定则采用默认主线程
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      //CallAdapter指的是对request处理的CallAdapter,可以添加多个
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Converter是对response执行转换处理返回的T,可以添加多个
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

platform.defaultCallbackExecutor()  Android 实现

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

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {//可以指定调用callback线程
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {//使用mainLooper的Handler post方式实现
      private final Handler handler = new Handler(Looper.getMainLooper());

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


CallAdapter接口定义

public interface CallAdapter<R, T> {
  //http 解析response 返回类型,不是咱接口定义泛型
  Type responseType();

  //处理response并转换为指定类型T
  T adapt(Call<R> call);

  //CallAdapter 创建获取
  abstract class Factory {
    /**
     * Returns a call adapter for interface methods that return {@code returnType}, or null if it
     * cannot be handled by this factory.
	 *根据接口返回类型,注解类型判断当前CallAdapter是否支持,不支持返回为null
     */
    public abstract CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);

    /**
     * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
     * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
	 *获取指定index泛型参数上限,例如Map<String, ? extends Runnable> index为1参数上限为Runnable
     */
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }

    /**
     * Extract the raw class type from {@code type}. For example, the type representing
     * {@code List<? extends Runnable>} returns {@code List.class}.
     */
	 //获取解析类型class,例如List<? extends Runnable>,返回List.class
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }


项目中有三种实现

RxJava Observable & Single - com.squareup.retrofit2:adapter-rxjava
Guava ListenableFuture - com.squareup.retrofit2:adapter-guava
Java 8 CompleteableFuture - com.squareup.retrofit2:adapter-java8

看一下java8实现

Java8CallAdapterFactory

private static final class BodyCallAdapter<R> implements CallAdapter<R, CompletableFuture<R>> {
    private final Type responseType;

    BodyCallAdapter(Type responseType) {
      this.responseType = responseType;
    }

    @Override public Type responseType() {
      return responseType;
    }

    @Override public CompletableFuture<R> adapt(final Call<R> call) {
      final CompletableFuture<R> future = new CompletableFuture<R>() {
        @Override public boolean cancel(boolean mayInterruptIfRunning) {
          if (mayInterruptIfRunning) {
            call.cancel();
          }
          return super.cancel(mayInterruptIfRunning);
        }
      };

      call.enqueue(new Callback<R>() {//调用okhttp Call方法异步调用
        @Override public void onResponse(Call<R> call, Response<R> response) {
          if (response.isSuccessful()) {
            future.complete(response.body());
          } else {
            future.completeExceptionally(new HttpException(response));
          }
        }

        @Override public void onFailure(Call<R> call, Throwable t) {
          future.completeExceptionally(t);
        }
      });

      return future;
    }
  }

可以看出网络请求是异步调用实现

看一下OkHttpCall.execute实现

@Override public Response<T> execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      ......

    if (canceled) {
      call.cancel();
    }
//内部调用okhttp excute发起网络请求,解析返回response
    return parseResponse(call.execute());
  }

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
   ......
    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }
到这里我们已取到数据结果

再看看转换如何实现ServiceMethod的toResponse

/** Builds a method return value from an HTTP response body. */
  R toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
  }

通过serviceMethod 中的Converter<ResponseBody, R> responseConverter;实现进行解析

Converter为转换接口,实现类有以下

  Gson - com.squareup.retrofit2:converter-gson
    Jackson - com.squareup.retrofit2:converter-jackson
    Moshi - com.squareup.retrofit2:converter-moshi
    Protobuf - com.squareup.retrofit2:converter-protobuf
    Wire - com.squareup.retrofit2:converter-wire
    Simple Framework - com.squareup.retrofit2:converter-simpleframework
    Scalars - com.squareup.retrofit2:converter-scalars

当然也可以自定义实现Converter,定制出符合自己需求转换器

从上面分析看出Retorfit中的3个核心部分:

1,Proxy     代理实现接口调用

2,CallAdapters   reques网络t处理
3,Converters    response解析转换对应泛型T返回数据结果




未完待续。。。


转载于:https://www.cnblogs.com/happyxiaoyu02/p/6150734.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值