Retrofit源码赏析五 —— CallAdapter

·  阅读 602
Retrofit源码赏析五 —— CallAdapter

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

通过前面的分析,我们知道在OkHttpCall中完成了请求,最后我们获取到的结果是Call类型,但是在实际使用中我们或许会和RxJava配合使用,需要的返回结果为Observable,这里使用了适配器模式,,只要指定对应的适配器就可以将返回的Call类型适配成我们需要的任意类型。

CallAdapter

public interface CallAdapter<R, T> {
  Type responseType();
  T adapt(Call<R> call);
}
  • responseType()返回泛型对应的真实类型。
  • adapt() 将Call类型适配成T类型。

CallAdapter.Factory

CallAdapter由CallAdapterFactory创建,他是CallAdapter的一个内部类。

abstract class Factory {
	public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
	protected static Type getParameterUpperBound(int index, ParameterizedType type) {
	  return Utils.getParameterUpperBound(index, type);
	}
	protected static Class<?> getRawType(Type type) {
	  return Utils.getRawType(type);
	}
}
  • get()方法会判断returnType,annotations是否和对应的CallAdapter匹配,如果匹配就返回adapter,否则返回null。
  • getParameterUpperBound() 获取泛型第index个参数的上界,比如index=1并且Map<String,? extends Runnable>就返回Runnable。
  • getRawType() 获取返回值的原始类型,例如List<? extends Runnable>就返回List。

get()方法一般都是3个作用,首先根据参数判断自己能否创建对应的CallAdapter,如果不能就返回null,由后面的Factory处理,然后对返回类型returnType进行校验,最后创建CallAdapter并返回。

Retrofit给我们提供了默认的CallAdapterFactory,在构建Retrofit实例的时候会初始化。

callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

根据不同的平台类型,提供默认的CallAdapterFactory也不一样。

List<? extends CallAdapter.Factory> defaultCallAdapterFactories( Executor callbackExecutor) {
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
}

DefaultCallAdapterFactory

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
	@Override
    public @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
	    if (getRawType(returnType) != Call.class) {
	      return null;
	    }
	    if (!(returnType instanceof ParameterizedType)) {
	      //抛出异常
	    }
	    return new CallAdapter
	}
}

DefaultCallAdapterFactory只能处理Call类型的返回结果,说明它处理的比较简单,只是对Call做了一下封装,然后判断返回类型是否为参数化类型,最后创建CallAdapter返回。

CallAdapter

return new CallAdapter<Object, Call<?>>() {
  public Type responseType() {
    return responseType;
  }
  public Call<Object> adapt(Call<Object> call) {
    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
  }
};

在executor不为空的情况下,会将Call适配成ExecutorCallbackCall类型,在ExecutorCallbackCall中主要是借助callbackExecutor完成了线程切换,这是因为OkHttp响应结果的线程没有在UI线程,对于Android而言,需要切换到UI线程才能操作UI,这里CallAdapter自动完成了切换。

RxJava2CallAdapterFactory

RxJava2CallAdapterFactory不在Retrofit核心包中,需要额外引入依赖并调用addCallAdapterFactory()注入。

public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
  public @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
		//1 判断能否适配当前类型
		Class<?> rawType = getRawType(returnType);
		//2 校验返回结果类型
		boolean isResult = false;
		boolean isBody = false;
		Type responseType;
		//3 返回CallAdapter
		return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
  }
}

判断能否适配当前类型

Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
  return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false, false, true);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
  return null;
}

Completable没有泛型类型,所以创建CallAdapter时候responseType参数类型传递为Void.class。

RxJava2CallAdapterFactory只支持Completable,Observable,Flowable,Single,Maybe几种类型,其余的类型无法处理,直接返回null。

返回结果校验

if (!(returnType instanceof ParameterizedType)) {
	throw new IllegalStateException();
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
	if (!(observableType instanceof ParameterizedType)) {
		throw new IllegalStateException();
	}
	responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
	if (!(observableType instanceof ParameterizedType)) {
		throw new IllegalStateException();
	}
  responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
  isResult = true;
} else {
  responseType = observableType;
  isBody = true;
}
  1. 判断返回类型是否为参数化类型。
  2. 获取实际类型,如果实际类型是Response或者Result,则需要observableType也是参数化类型。

RxJava2CallAdapter

由于支持的类型过多,这里省略部分。

final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
	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;
	    }
		//省略部分处理
	    return RxJavaPlugins.onAssembly(observable);
  }
}

默认情况下,我们使用的是RxJava2CallAdapterFactory#create()创建的工厂,这种情况下isAsync为false,所以首先生成的是CallExecuteObservable对象。

CallExecuteObservable是Observable的子类,它完成了对Call的转换。

final class CallExecuteObservable<T> extends Observable<Response<T>> {
	protected void subscribeActual(Observer<? super Response<T>> observer) {
		//只保留了主流程
		try {
		  Response<T> response = call.execute();
		  observer.onNext(response);
		  observer.onComplete();
		} catch (Throwable t) {
		  //异常处理
		}
	}
}

熟悉RxJava2的朋友都比较熟悉这里,通过observer将call执行的结果发射出去,如果执行顺利就发射onComplete事件,否则发射onError事件。

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改