What柒巫?
它是Square公司開發(fā)的一個(gè)強(qiáng)大的網(wǎng)絡(luò)庫(kù)!基于Okhttp谷丸,支持RxJava。
Why?
為什么要學(xué)它应结,因?yàn)樗鼉?yōu)秀刨疼!不信你點(diǎn)擊下圖看看!
功能強(qiáng)大
1.基于Okhttp&遵循Restful API設(shè)計(jì)風(fēng)格
2.通過(guò)注解配置網(wǎng)絡(luò)請(qǐng)求參數(shù)
4.支持同步&異步網(wǎng)絡(luò)請(qǐng)求
5.支持多種數(shù)據(jù)解析&序列化格式(Gson,Json,XML鹅龄,Protobuf)
6.提供RxJava支持優(yōu)點(diǎn)
功能強(qiáng)大揩慕,簡(jiǎn)潔易用,可擴(kuò)展性好
HOW?
說(shuō)了這么多用個(gè)試試扮休!
public interface ApiService {
@GET("/")
Call<ResponseBody> getRetrofitTest();
}
public void retrofit(){
Retrofit retrofit =new Retrofit.Builder().baseUrl("https://www.baidu.com").build();
ApiService apiService=retrofit.create(ApiService.class);
apiService.getRetrofitTest().enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.i("retrofit",response.message());
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("retrofit",t.toString());
}
});
}
Code分析
基本流程
1.使用建造者模式實(shí)例化Retrofit
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.baidu.com").addConverterFactory
(GsonConverterFactory.create()).build();
2.使用注解方式構(gòu)建Call請(qǐng)求方法| 參數(shù)...
@GET("/")
Call<ResponseBody> getRetrofitTest();
3.使用動(dòng)態(tài)代理實(shí)現(xiàn)請(qǐng)求接口
ApiService apiService = retrofit.create(ApiService.class);
4.異步請(qǐng)求方法調(diào)用迎卤,回調(diào)返回結(jié)果
apiService.getRetrofitTest().enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.i("retrofit", response.message());
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("retrofit", t.toString());
}
});
流程詳解
流程1
Builder模式實(shí)例化retrofit三步驟
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.baidu.com").addConverterFactory
(GsonConverterFactory.create()).build();
步驟 1
這個(gè)函數(shù)做了什么呢?
1.對(duì)變量是否為空判斷玷坠,并附上默認(rèn)的值
2.然后new 出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();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
步驟2 設(shè)置配置參數(shù)
這里只是舉兩個(gè)配置參數(shù)的例子
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
步驟3 分析Retrofit常量&方法
public final class Retrofit {
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;//請(qǐng)求URL
final List<Converter.Factory> converterFactories;//數(shù)據(jù)轉(zhuǎn)換器集合
final List<CallAdapter.Factory> callAdapterFactories;//網(wǎng)絡(luò)請(qǐng)求適配器集合
final @Nullable Executor callbackExecutor;//線程切換執(zhí)行器
final boolean validateEagerly;//驗(yàn)證
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
變量詳解
1.HttpUrl baseUrl
/**
* Set the API base URL.
*
* @see #baseUrl(HttpUrl)
*把String類型的url參數(shù)轉(zhuǎn)化為適合OKhttp的HttpUrl類型
*/
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
/**
* Set the API base URL.
*
* @see #baseUrl(HttpUrl)
*/
public Builder baseUrl(URL baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl.toString()));
}
/**
* Set the API base URL.
*
* @see #baseUrl(URL)
*/
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");//檢測(cè)是否空
List<String> pathSegments = baseUrl.pathSegments();//切割判斷
//判斷最后一個(gè)字段要以 / 結(jié)尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
2. final List<Converter.Factory> converterFactories;
數(shù)據(jù)轉(zhuǎn)換器工廠的集合
作用:放置數(shù)據(jù)轉(zhuǎn)換器工廠
數(shù)據(jù)轉(zhuǎn)換器工廠作用:生產(chǎn)數(shù)據(jù)轉(zhuǎn)換器(converter)
/** Add converter factory for serialization and deserialization of objects.
*添加轉(zhuǎn)換器工廠以進(jìn)行對(duì)象的序列化和反序列化蜗搔。
* */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
所有定義只要實(shí)現(xiàn)Converter這個(gè)接口,數(shù)據(jù)F轉(zhuǎn)換T
public interface Converter<F, T> {
//實(shí)現(xiàn)從 F(rom) 到 T(o)的轉(zhuǎn)換
@Nullable T convert(F value) throws IOException;
/** Creates {@link Converter} instances based on a type and target usage. */
abstract class Factory {
/**
* 這里創(chuàng)建從ResponseBody其它類型的Converter劲藐,如果不能處理返回null
* 主要用于對(duì)響應(yīng)體的處理
*/
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
在這里創(chuàng)建 從自定類型到RequestBody 的Converter,不能處理就返回null,
主要用于對(duì)Part樟凄、PartMap聘芜、Body注解的處理
*/
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
/**
這里用于對(duì)Field、FieldMap缝龄、Header汰现、Path、Query叔壤、QueryMap注解的處理
Retrfofit對(duì)于上面的幾個(gè)注解默認(rèn)使用的是調(diào)用toString方法
*/
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
/**
* 根據(jù)下標(biāo)index,提取泛型參數(shù)
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* 根據(jù)泛型提取類
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
3. final List<CallAdapter.Factory> callAdapterFactories;
網(wǎng)絡(luò)請(qǐng)求適配器工廠的集合
作用:放置網(wǎng)絡(luò)請(qǐng)求適配器工廠
網(wǎng)絡(luò)請(qǐng)求適配器工廠作用:生產(chǎn)網(wǎng)絡(luò)請(qǐng)求適配器(CallAdapter)
Call在Retrofit里默認(rèn)是OkHttpCall
/**
* 網(wǎng)絡(luò)請(qǐng)求適配器
* @param <T>
*/
final class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, T> responseConverter;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
// 構(gòu)造方法
OkHttpCall(RequestFactory requestFactory, Object[] args,
okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
@Override public retrofit2.OkHttpCall<T> clone() {
return new retrofit2.OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
}
@Override public synchronized Request request() {
okhttp3.Call call = rawCall;
if (call != null) {
return call.request();
}
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw new RuntimeException("Unable to create request.", creationFailure);
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
try {
return (rawCall = createRawCall()).request();
} catch (RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
} catch (IOException e) {
creationFailure = e;
throw new RuntimeException("Unable to create request.", e);
}
}
//異步執(zhí)行網(wǎng)絡(luò)請(qǐng)求
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//獲取真正的網(wǎng)絡(luò)請(qǐng)求對(duì)象
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
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) {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(retrofit2.OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(retrofit2.OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
@Override public synchronized boolean isExecuted() {
return executed;
}
//同步執(zhí)行網(wǎng)絡(luò)請(qǐng)求方法
@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 if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//解析網(wǎng)絡(luò)返回?cái)?shù)據(jù)
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 retrofit2.OkHttpCall.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);
}
retrofit2.OkHttpCall.ExceptionCatchingResponseBody catchingBody = new retrofit2.OkHttpCall.ExceptionCatchingResponseBody(rawBody);
try {
//格式轉(zhuǎn)換
T body = responseConverter.convert(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;
}
}
public void cancel() {
canceled = true;
okhttp3.Call call;
synchronized (this) {
call = rawCall;
}
if (call != null) {
call.cancel();
}
}
@Override public boolean isCanceled() {
if (canceled) {
return true;
}
synchronized (this) {
return rawCall != null && rawCall.isCanceled();
}
}
static final class NoContentResponseBody extends ResponseBody {
private final @Nullable
MediaType contentType;
private final long contentLength;
NoContentResponseBody(@Nullable MediaType contentType, long contentLength) {
this.contentType = contentType;
this.contentLength = contentLength;
}
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return contentLength;
}
@Override public BufferedSource source() {
throw new IllegalStateException("Cannot read raw response body of a converted body.");
}
}
static final class ExceptionCatchingResponseBody extends ResponseBody {
private final ResponseBody delegate;
private final BufferedSource delegateSource;
@Nullable IOException thrownException;
ExceptionCatchingResponseBody(ResponseBody delegate) {
this.delegate = delegate;
this.delegateSource = Okio.buffer(new ForwardingSource(delegate.source()) {
@Override public long read(Buffer sink, long byteCount) throws IOException {
try {
return super.read(sink, byteCount);
} catch (IOException e) {
thrownException = e;
throw e;
}
}
});
}
@Override public MediaType contentType() {
return delegate.contentType();
}
@Override public long contentLength() {
return delegate.contentLength();
}
@Override public BufferedSource source() {
return delegateSource;
}
@Override public void close() {
delegate.close();
}
void throwIfCaught() throws IOException {
if (thrownException != null) {
throw thrownException;
}
}
}
}
在Retrofit中提供了四種CallAdapterFactory: ExecutorCallAdapterFactory(默認(rèn))瞎饲、GuavaCallAdapterFactory、Java8CallAdapterFactory炼绘、RxJavaCallAdapterFactory
4. private @Nullable Executor callbackExecutor;線程切換
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
//切換到主線程顯示結(jié)果
@Override public void execute(Runnable r) {
handler.post(r);
}
}
@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);
}
});
}
});
}
5. final boolean validateEagerly;判斷是否需要驗(yàn)證
if (validateEagerly) {
eagerlyValidateMethods(service);
}
6.private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
網(wǎng)絡(luò)請(qǐng)求配置對(duì)象(對(duì)網(wǎng)絡(luò)請(qǐng)求接口中方法注解進(jìn)行解析后得到的對(duì)象)
作用:存儲(chǔ)網(wǎng)絡(luò)請(qǐng)求相關(guān)的配置嗅战,如網(wǎng)絡(luò)請(qǐng)求的方法蛛淋、數(shù)據(jù)轉(zhuǎn)換器逐样、網(wǎng)絡(luò)請(qǐng)求適配器、網(wǎng)絡(luò)請(qǐng)求//工廠劫侧、基地址等
/**
*通過(guò)注解方式獲取配置對(duì)象 實(shí)現(xiàn)緩存
*/
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
主要分方法
1.動(dòng)態(tài)方法實(shí)現(xiàn)注解接口
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();
private final Object[] emptyArgs = new Object[0];
@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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
2.解析緩存注解等參數(shù)
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
3.網(wǎng)絡(luò)請(qǐng)求適配器
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
4.實(shí)現(xiàn)適配器方法
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
5.正真的請(qǐng)求和返回參數(shù)的類
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@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);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}
結(jié)合RxJava用RxJava2CallAdapter
//第一步創(chuàng)建工廠CallAdapterFactory
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//第二步實(shí)例化工廠方法
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
//第三步創(chuàng)建網(wǎng)絡(luò)適配器RxJava2CallAdapter
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
//第四步傳入Call請(qǐng)求器到RxJava2CallAdapter
@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;
}
//第五步具體實(shí)現(xiàn)方法
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallEnqueueObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
private static final class CallCallback<T> implements Disposable, Callback<T> {
private final Call<?> call;
private final Observer<? super Response<T>> observer;
boolean terminated = false;
CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
this.call = call;
this.observer = observer;
}
@Override public void onResponse(Call<T> call, Response<T> response) {
if (call.isCanceled()) return;
try {
observer.onNext(response);
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!call.isCanceled()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
@Override public void onFailure(Call<T> call, Throwable t) {
if (call.isCanceled()) return;
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
@Override public void dispose() {
call.cancel();
}
@Override public boolean isDisposed() {
return call.isCanceled();
}
}
}