本文是對(duì)之前寫(xiě)的兩篇文章的綜合概述及全流程梳理
Android 利用RxJava和Retrofit搭建網(wǎng)絡(luò)請(qǐng)求組件——監(jiān)聽(tīng)回調(diào)及部分源碼解析
Android 利用RxJava和Retrofit搭建網(wǎng)絡(luò)請(qǐng)求組件——基礎(chǔ)配置及部分源碼解析
基礎(chǔ)配置
一.定義網(wǎng)絡(luò)請(qǐng)求方法的接口文件:ApiService.class(名字隨意)
ApiService.class定義了各個(gè)請(qǐng)求方法昙楚,請(qǐng)求方式及參數(shù)類型均以注解形式標(biāo)識(shí)愿棋,示例文件僅描述了GET與POST請(qǐng)求方式
/**
* 注意:ApiService 必須是接口,且不能實(shí)現(xiàn)其他接口
* Created by cuiyan on 16-10-18.
*/
public interface ApiService {
/*************************GET 請(qǐng)求方式*************************/
/**
* ApiConstants.QQ_SPORT_API 請(qǐng)求接口地址api(相對(duì)路徑)
* 域名或ip部分會(huì)在構(gòu)建Retrofit時(shí)設(shè)置
* 返回Observable對(duì)象(內(nèi)部包裝了Call實(shí)例)科展,訂閱(subscribe)執(zhí)行時(shí)會(huì)調(diào)用Call.execute()方法發(fā)送網(wǎng)絡(luò)請(qǐng)求。
* 默認(rèn)情況下糠雨,返回結(jié)果為retrofit2.Call對(duì)象才睹,只有在構(gòu)建Retrofit實(shí)例時(shí)設(shè)置了RxJava2CallAdapterFactory才支持請(qǐng)求方法返回Observable對(duì)象
*/
@GET(ApiConstants.QQ_SPORT_API)
Observable<NewsResult> getQQSportNews(@Query("baid") String baid, @Query("apikey") String apiKey);
@GET(ApiConstants.QQ_SPORT_API)
Observable<NewsResult> getQQSportNews1(@QueryMap Map<String, String> paramsMap);
/*************************POST 請(qǐng)求方式*************************/
/**
* @Body 注解參數(shù)均表示以實(shí)體形式提交請(qǐng)求數(shù)據(jù)
*/
@POST(ApiConstants.QQ_SPORT_API)
Observable<NewsResult> getQQSportNews2(@Body NewsResult bodyParam);
/**
* @Field 或 @FieldMap 注解參數(shù)均表示以表單形式提交參數(shù),相應(yīng)的甘邀,
* 請(qǐng)求方法必須添加 @FormUrlEncoded 注解
*/
@FormUrlEncoded
@POST(ApiConstants.QQ_SPORT_API)
Observable<NewsResult> getQQSportNews3(@Field("baid") String baid, @Field("apikey") String apiKey);
@FormUrlEncoded
@POST(ApiConstants.QQ_SPORT_API)
Observable<NewsResult> getQQSportNews4(@FieldMap Map<String, String> paramsMap);
}
二.ApiService實(shí)例構(gòu)建及相關(guān)配置
public class BaseServiceUtil {
private static final int DEFAULT_TIMEOUT = 10;
/**
@param serviceClass 網(wǎng)絡(luò)請(qǐng)求接口描述文件類琅攘,步驟一中的ApiService.class或其他類似class
@return S S實(shí)例,即ApiService實(shí)例
*/
public static synchronized <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null);
}
public static <S> S createService(Class<S> serviceClass, String baseUrl) {
CommonInterceptor interceptor = new CommonInterceptor();
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create()) // 設(shè)置Converter.Factory(請(qǐng)求響應(yīng)數(shù)據(jù)轉(zhuǎn)換器)松邪,我們?cè)O(shè)置的是GsonConverterFactory
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()); // 重點(diǎn)1:為Retrofit設(shè)置CallAdapter.Factory坞琴,這里我們?cè)O(shè)置的是RxJava2CallAdapterFactory。ApiService 中網(wǎng)絡(luò)請(qǐng)求方法默認(rèn)返回retrofit2.Call對(duì)象逗抑,添加RxJava2CallAdapterFactory后支持返回Observable對(duì)象
// retrofitBuilder.callFactory()
// 一定要設(shè)置且必須格式正確的baseUrl
if (!TextUtils.isEmpty(baseUrl)) {
retrofitBuilder.baseUrl(baseUrl);
} else {
retrofitBuilder.baseUrl(BuildConfig.BASE_URL);
}
clientBuilder.interceptors().clear();
clientBuilder.interceptors().add(interceptor); // 重點(diǎn)2:為OkHttpClient(實(shí)現(xiàn)了okhttp3.Call.Factory接口)設(shè)置攔截器
// 設(shè)置https證書(shū)
// try {
// clientBuilder.sslSocketFactory(RqbTrustManager.getInstance().getSSLSocketFactory("BKS", R.raw.rqb_ssl));
// } catch (Exception e) {
// e.printStackTrace();
// }
OkHttpClient client = clientBuilder.build();
// 重點(diǎn)3:為Retrofit設(shè)置okhttp3.Call.Factory丘喻,OkHttpClient實(shí)現(xiàn)了okhttp3.Call.Factory接口,該方法內(nèi)實(shí)際調(diào)用了
// callFactory(okhttp3.Call.Factory factory)方法為Retrofit設(shè)置okhttp3.Call.Factory钮蛛。此行與下一行可合并运授,此處有意拆開(kāi)做標(biāo)注
retrofitBuilder.client(client);
// 重點(diǎn)4:構(gòu)建Retrofit實(shí)例
Retrofit retrofit = retrofitBuilder.build();
// 重點(diǎn)5:構(gòu)建ApiService實(shí)例
return retrofit.create(serviceClass);
}
}
三.網(wǎng)絡(luò)請(qǐng)求訂閱者(觀察者)
/**
* 網(wǎng)絡(luò)請(qǐng)求訂閱者
* Created by cuiyan on 16/6/2 14:09
*/
public class NetRequestSubscriber<T> implements Observer<T> {
private Dialog progressDialog;
private Disposable disposable;
private NetRequestCallback<T> netRequestCallback;
private Context context;
/**
* @param netRequestCallback 網(wǎng)絡(luò)請(qǐng)求回調(diào)
*/
public NetRequestSubscriber(@NonNull NetRequestCallback<T> netRequestCallback, Context context) {
this(netRequestCallback, context, false, null);
}
/**
* @param netRequestCallback 網(wǎng)絡(luò)請(qǐng)求回調(diào)
* @param showProgress 是否顯示網(wǎng)絡(luò)請(qǐng)求加載對(duì)話框
* @param progressTip loading提示語(yǔ)
* @see NetProgressDialog
*/
public NetRequestSubscriber(@NonNull final NetRequestCallback<T> netRequestCallback, Context context, boolean showProgress, String progressTip) {
this.netRequestCallback = netRequestCallback;
this.context = context;
if (showProgress) {
progressDialog = NetProgressDialog.getInstance(context, progressTip, new OnNetProgressCancelListener() {
@Override
public void onCancelRequest() {
cancelRequest()
}
});
}
}
/**
* @param netRequestCallback 網(wǎng)絡(luò)請(qǐng)求回調(diào)
* @param progressDialog dialog 自定義對(duì)話框
*/
public NetRequestSubscriber(@NonNull NetRequestCallback<T> netRequestCallback, Context context, @NonNull Dialog progressDialog) {
this.netRequestCallback = netRequestCallback;
this.context = context;
this.progressDialog = progressDialog;
}
@Override
public void onSubscribe(@NonNull Disposable d) {
this.disposable = d;
showProgress();
onRequestStart();
}
@Override
public synchronized void onNext(final T t) {
if (t == null) {
onRequestResultNull();
} else {
if (t instanceof BaseResult && !Config.REQUEST_SUCCESS_CODE.equals(((BaseResult) t).getCode())) {
ToastUtil.showToast(context, ((BaseResult) t).getMessage());
}
onRequestSuccess(t);
}
}
@Override
public synchronized void onError(Throwable throwable) {
dismissProgress();
onRequestError(throwable);
if (throwable instanceof HttpException) {
ToastUtil.showToast(context, ((HttpException) throwable).message() + ((HttpException) throwable).code());
} else {
if (BuildConfig.DEBUG) {
ToastUtil.showToast(context, "error:" + throwable.getMessage());
} else {
ToastUtil.showToast(context, context.getString(R.string.error_net_request_failed));
}
}
}
/**
* {@link NetRequestSubscriber#onError(Throwable)}
* {@link Observer#onError(Throwable)}
* {@link Observer#onComplete()} (Throwable)}
* 該方法與onError方法互斥
*/
@Override
public void onComplete() {
dismissProgress();
netRequestCallback.onFinish();
}
private void onRequestStart() {
if (Looper.myLooper() != context.getMainLooper()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
netRequestCallback.onStart();
}
});
} else {
netRequestCallback.onStart();
}
}
private void onRequestSuccess(final T t) {
if (Looper.myLooper() != context.getMainLooper()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
netRequestCallback.onSuccess(t);
}
});
} else {
netRequestCallback.onSuccess(t);
}
}
private void onRequestResultNull() {
if (Looper.myLooper() != context.getMainLooper()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
netRequestCallback.onResultNull();
}
});
} else {
netRequestCallback.onResultNull();
}
}
private void onRequestError(final Throwable throwable) {
throwable.printStackTrace();
if (Looper.myLooper() != context.getMainLooper()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
netRequestCallback.onError(throwable);
netRequestCallback.onFinish();
}
});
} else {
netRequestCallback.onError(throwable);
netRequestCallback.onFinish();
}
}
/**
*
*
*/
private void showProgress() {
if (progressDialog != null && !progressDialog.isShowing()) {
progressDialog.show();
}
}
private void dismissProgress() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
public void cancelRequest() {
dismissProgress();
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
}
netRequestCallback.onCancel();
netRequestCallback.onFinish();
}
}
四.網(wǎng)絡(luò)請(qǐng)求控制器
public class BaseController {
/**
* @param subscriber 訂閱者
*/
@SuppressWarnings("unchecked")
public static synchronized void sendRequest(final NetRequestSubscriber subscriber, Observable observable) {
observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(subscriber);
}
/**
* @param activity 用于與observable綁定,activity生命周期結(jié)束時(shí),自動(dòng)取消訂閱
* @param observable 被觀察者
* @param subscriber 訂閱者
*/
@SuppressWarnings("unchecked")
public static synchronized void sendRequest(RxActivity activity, final NetRequestSubscriber subscriber, Observable observable) {
observable.subscribeOn(Schedulers.io())
.compose(activity.bindToLifecycle()) //防止內(nèi)存泄漏,activity生命周期結(jié)束后取消訂閱
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
/**
* @param fragment 用于與observable綁定,fragment生命周期結(jié)束時(shí),自動(dòng)取消訂閱
* @param subscriber 訂閱者
*/
@SuppressWarnings("unchecked")
public static synchronized void sendRequest(RxFragment fragment, final NetRequestSubscriber subscriber, Observable observable) {
observable.compose(fragment.bindToLifecycle()) //防止內(nèi)存泄漏,fragment生命周期結(jié)束后取消訂閱
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
}
上述代碼構(gòu)建了完整網(wǎng)絡(luò)請(qǐng)求功能咏尝,下面貼出應(yīng)用示例。完整示例:https://github.com/670832188/TestApp
private void getNews() {
NetRequestSubscriber<NewsResult> subscriber = new NetRequestSubscriber<>(new NetRequestCallback<NewsResult>() {
@Override
public void onStart() {
setContentState(STATE_NET_PROGRESS);
}
@Override
public void onSuccess(@NonNull NewsResult newsResult) {
if (newsResult.getData() != null && newsResult.getData().size() > 0) {
setContentState(STATE_DATA_CONTENT);
newsAdapter.updateDataList(newsResult.getData());
} else {
setContentState(STATE_DATA_EMPTY);
}
}
@Override
public void onResultNull() {
setContentState(STATE_NET_ERROR);
}
@Override
public void onError(Throwable throwable) {
setContentState(STATE_NET_ERROR);
}
@Override
public void onCancel() {
super.onCancel();
}
@Override
public void onFinish() {
super.onFinish();
}
}, this);
Observable<NewsResult> observable = BaseServiceUtil.createService(ApiService.class, ApiConstants.JUHE_BASE_URL).getQQSportNews("69", Constant.JUHE_API_KEY);
BaseController.sendRequest(this, subscriber, observable);
}
流程梳理
上述代碼中標(biāo)注了五處重點(diǎn):
1.Retrofit設(shè)置RxJava2CallAdapterFactory褂傀;
2.OkHttpClient(okhttp3.Call.Factory)設(shè)置Interceptor;
3.Retrofit設(shè)置OkHttpClient(okhttp3.Call.Factory);
4.構(gòu)建Retrofit實(shí)例
5.構(gòu)建ApiService實(shí)例
下面從Retrofit和ApiService實(shí)例構(gòu)建為入口羞酗,分析基本流程及上述上述幾個(gè)配置是如何工作的
先看一下創(chuàng)建Retrofit實(shí)例的方法Retrofit.build()源碼
1. public Retrofit build() {
2. if (baseUrl == null) {
3. throw new IllegalStateException("Base URL required.");
4. }
5. okhttp3.Call.Factory callFactory = this.callFactory;
6. if (callFactory == null) {
7. callFactory = new OkHttpClient();
8. }
9. Executor callbackExecutor = this.callbackExecutor;
10. if (callbackExecutor == null) {
11. callbackExecutor = platform.defaultCallbackExecutor();
12. }
13. // Make a defensive copy of the adapters and add the default Call adapter.
14. List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
15. adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
16. // Make a defensive copy of the converters.
17. List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
18. return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,callbackExecutor, validateEagerly);
19. }
第1-第3行:首先檢測(cè)了之前設(shè)置的baseUrl,沒(méi)有設(shè)置的話直接拋出異常紊服。
第5-第8行:檢測(cè)是否設(shè)置了okhttp3.Call.Factory檀轨,沒(méi)有設(shè)置的話使用默認(rèn)的OkHttpClient實(shí)例(前述代碼中說(shuō)過(guò)OkHttpClient實(shí)現(xiàn)了okhttp3.Call.Factory接口)。我們?cè)诖a中創(chuàng)建欺嗤、配置了OkHttpClient實(shí)例(設(shè)置超時(shí)時(shí)間参萄、攔截器),并設(shè)置于Retrofit實(shí)例煎饼。之所以沒(méi)有使用默認(rèn)的OkHttpClient讹挎,是因?yàn)槲覀冃枰鶕?jù)需求自定義超時(shí)時(shí)間、攔截器等
第14-15行:獲取CallAdapter.Factory列表,包括我們?cè)O(shè)置的RxJava2CallAdapterFactory和框架內(nèi)置的默認(rèn)CallAdapter.Factory筒溃,追蹤源碼可以看到马篮,內(nèi)置的是ExecutorCallAdapterFactory.ExecutorCallbackCall。
注意:列表的順序怜奖,先添加的是我們?cè)O(shè)置的RxJava2CallAdapterFactory浑测,請(qǐng)記住我們的RxJava2CallAdapterFactory是NO.1 NO.1 NO.1
第17行:獲取Converter.Factory列表,包括我們?cè)O(shè)置的GsonConverterFactory和內(nèi)置的Converter.Factory(參見(jiàn)Rerofit.Builder構(gòu)造方法)歪玲。
第18行:callFactory迁央、adapterFactories 等作為構(gòu)建參數(shù)傳入Retrofit構(gòu)造方法創(chuàng)建Retrofit實(shí)例,看一下其構(gòu)造方法:
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
成員變量callFactory 是我們?cè)O(shè)置的OkHttpClient滥崩;converterFactories包含了我們?cè)O(shè)置的GsonConverterFactory岖圈;adapterFactories 包含了我們?cè)O(shè)置的RxJava2CallAdapterFactory。暫且先有些印象钙皮,方便后續(xù)分析蜂科。
下面看ApiService實(shí)例構(gòu)建方法Retrofit .create(final Class<T> service)源碼:
1. public <T> T create(final Class<T> service) {
2. Utils.validateServiceInterface(service);
3. if (validateEagerly) {
4. eagerlyValidateMethods(service);
5. }
6. return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
7. new InvocationHandler() {
8. private final Platform platform = Platform.get();
9. @Override
10 public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
11. // If the method is a method from Object then defer to normal invocation.
12. if (method.getDeclaringClass() == Object.class) {
13. return method.invoke(this, args);
14. }
15. if (platform.isDefaultMethod(method)) {
16. return platform.invokeDefaultMethod(method, service, proxy, args);
17. }
18. ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
19. OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); // 請(qǐng)留意okHttpCall
20. return serviceMethod.callAdapter.adapt(okHttpCall); // 請(qǐng)留心callAdapter
21. }
22. });
23. }
很直接、很暴力啊短条,利用Proxy創(chuàng)建的ApiService代理對(duì)象导匣。查看InvocationHandler的invoke方法,看看代理操作做了什么處理慌烧。我們只關(guān)心我們的網(wǎng)絡(luò)請(qǐng)求方法逐抑,我們的網(wǎng)絡(luò)請(qǐng)求方法都是ApiService定義的鸠儿,第12行判斷條件不滿足屹蚊,pass;第15行判斷條件也不成立进每,具體原因可查看platform的創(chuàng)建方法汹粤。
現(xiàn)在只剩下18-20行是我們需要關(guān)心的。先看第20行田晚,我們的網(wǎng)絡(luò)請(qǐng)求被萬(wàn)惡的代理商劫持了嘱兼,返回結(jié)果是serviceMethod.callAdapter.adapt(okHttpCall),如果你的記憶不是很差的話贤徒,應(yīng)該記得我們的請(qǐng)求方法返回的Observable對(duì)象芹壕。是很明顯,我們需要知道這個(gè)callAdapter是什么接奈,了解它的adapt方法起到了什么作用踢涌。定位到第18行,深入loadServiceMethod方法窺視一下
1. ServiceMethod<?, ?> loadServiceMethod(Method method) {
2. ServiceMethod<?, ?> result = serviceMethodCache.get(method);
3. if (result != null) return result;
4. synchronized (serviceMethodCache) {
5. result = serviceMethodCache.get(method);
6. if (result == null) {
7. result = new ServiceMethod.Builder<>(this, method).build();
8. serviceMethodCache.put(method, result);
9. }
10. }
11. return result;
12. }
很遺憾序宦,這個(gè)方法沒(méi)有窺測(cè)到ServiceMethod是神馬角色睁壁。定位到上述代碼第7行,繼續(xù)追擊ServiceMethod(ServiceMethod.class)
1. Builder(Retrofit retrofit, Method method) {
2. this.retrofit = retrofit;
3. this.method = method;
4. this.methodAnnotations = method.getAnnotations();
5. this.parameterTypes = method.getGenericParameterTypes();
6. this.parameterAnnotationsArray = method.getParameterAnnotations();
7. }
8. public ServiceMethod build() {
9. callAdapter = createCallAdapter();
10. responseType = callAdapter.responseType();
11. if (responseType == Response.class || responseType == okhttp3.Response.class) {
12. throw methodError("'"+ Utils.getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?");
13. }
14. responseConverter = createResponseConverter();
15. for (Annotation annotation : methodAnnotations) {
16 parseMethodAnnotation(annotation);
17. }
18. // 此處省略一萬(wàn)個(gè)字...
19. return new ServiceMethod<>(this); // 此處要記住,后面有用
20. }
// 構(gòu)造方法一并看了
21. ServiceMethod(Builder<R, T> builder) {
22. this.callFactory = builder.retrofit.callFactory(); // 此處請(qǐng)留意
23. this.callAdapter = builder.callAdapter;
24. this.baseUrl = builder.retrofit.baseUrl();
25. this.responseConverter = builder.responseConverter;
26. this.httpMethod = builder.httpMethod;
27. this.relativeUrl = builder.relativeUrl;
28. this.headers = builder.headers;
29. this.contentType = builder.contentType;
30. this.hasBody = builder.hasBody;
31. this.isFormEncoded = builder.isFormEncoded;
32. this.isMultipart = builder.isMultipart;
33. this.parameterHandlers = builder.parameterHandlers;
34. }
看Builder構(gòu)造方法第2行潘明,ServiceMethod持有我們之前創(chuàng)建的Retrofit實(shí)例行剂。再看第9行callAdapter = createCallAdapter(); 我們要找的callAdapter(CallAdapter)終于浮出水面钳降。我們之前說(shuō)過(guò)厚宰,創(chuàng)建Retrofit實(shí)例的時(shí)候我們?yōu)槠湓O(shè)置了CallAdapter.Factory,就是那個(gè)RxJava2CallAdapterFactory...(此處伏筆~~)牲阁。
從第9行繼續(xù)追蹤源碼固阁,最終定位到Retrofit的nextCallAdapter方法,此方法返回的CallAdapter就是我們要尋找的目標(biāo)了
1. public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
2. checkNotNull(returnType, "returnType == null");
3. checkNotNull(annotations, "annotations == null");
4. int start = adapterFactories.indexOf(skipPast) + 1;
5. for (int i = start, count = adapterFactories.size(); i < count; i++) {
6. CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
7. if (adapter != null) {
8. return adapter;
9. }
10. }
11. // 此處省略一萬(wàn)字(異常處理相關(guān))
12. }
這段代碼很就容易看懂了~城菊。遍歷CallAdapter.Factory列表备燃,通過(guò)Factory的get方法獲取匹配的CallAdapter,一猜就是通過(guò)我們?cè)O(shè)置的RxJava2CallAdapterFactory獲取的凌唬。為什么這么說(shuō)呢并齐?還記得之前我們說(shuō)過(guò),我們?cè)O(shè)置的RxJava2CallAdapterFactory是第一順位客税,狀元郎况褪。看一下第4行更耻,遍歷起點(diǎn)位置start值是多少测垛?如果你自己追蹤到這塊代碼,就會(huì)知道skipPast為null秧均,所以start等于0食侮,因此是從頭到尾遍歷列表,而我們的RxJava2CallAdapterFactory處于列表第一位目胡。那就看一看RxJava2CallAdapterFactory部分源碼吧
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
/**
* Returns an instance which creates synchronous observables that do not operate on any scheduler
* by default.
*/
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
@Override
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);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable"
: isSingle ? "Single"
: isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
}
上述源碼做了刪減锯七,只保留了我們關(guān)心的部分。我們?cè)谠O(shè)置RxJava2CallAdapterFactory時(shí)誉己,使用的是RxJava2CallAdapterFactory無(wú)參靜態(tài)方法create()創(chuàng)建的RxJava2CallAdapterFactory實(shí)例眉尸,顯然scheduler為null,isAsync為false巨双。繼續(xù)看get方法噪猾,定位到return語(yǔ)句,返回的是RxJava2CallAdapter筑累,構(gòu)造RxJava2CallAdapter實(shí)例時(shí)傳入了一堆參數(shù)袱蜡,我們關(guān)心一下scheduler、isAsync和isBody參數(shù)疼阔,不過(guò)多解析該方法戒劫,請(qǐng)自行深度查閱半夷。scheduler為null,isAsync為false迅细,isBody為true巫橄,以此為基礎(chǔ)繼續(xù)看RxJava2CallAdapter源碼,代碼不多,全部貼出
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
private final Type responseType;
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private final boolean isResult;
private final boolean isBody;
private final boolean isFlowable;
private final boolean isSingle;
private final boolean isMaybe;
private final boolean isCompletable;
// 構(gòu)造方法
RxJava2CallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe,
boolean isCompletable) {
this.responseType = responseType;
this.scheduler = scheduler;
this.isAsync = isAsync;
this.isResult = isResult;
this.isBody = isBody;
this.isFlowable = isFlowable;
this.isSingle = isSingle;
this.isMaybe = isMaybe;
this.isCompletable = isCompletable;
}
@Override public Type responseType() {
return responseType;
}
@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) {
// 這個(gè)是該方法最終返回的Observable對(duì)象
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;
}
}
直接看adapt方法第一行responseObservable茵典,是一個(gè)Observable對(duì)象湘换,該方法最終返回的也是Observable對(duì)象,且與responseObservable相關(guān)统阿。先看看responseObservable吧彩倚,前述說(shuō)過(guò)isAsync為false,所以responseObservable是CallExecuteObservable實(shí)例扶平,感興趣您也可以看看CallEnqueueObservable源碼(Android 利用RxJava和Retrofit搭建網(wǎng)絡(luò)請(qǐng)求組件——監(jiān)聽(tīng)回調(diào)及部分源碼解析中有所提及)帆离。之前還說(shuō)過(guò)scheduler為null,isBody為true结澄,綜合下來(lái)哥谷,最終return的是BodyObservable對(duì)象(對(duì)于其他情形可自行查閱相關(guān)代碼),該BodyObservable實(shí)例的構(gòu)造參數(shù)是responseObservable(CallExecuteObservable)麻献。不管怎樣们妥,BodyObservable確實(shí)是Observable,看來(lái)代理商并沒(méi)有做什么壞事勉吻,真的與ApiService中我們期望的結(jié)果一樣监婶。到此為止,我們已經(jīng)知曉ApiService是如何返回Observable對(duì)象了齿桃,主動(dòng)脈已經(jīng)打通惑惶。不再分析BodyObservable源碼,讀者可自行查看源譬,只是做了相關(guān)封裝處理集惋,相對(duì)比較簡(jiǎn)單孕似。接下來(lái)繼續(xù)分析CallExecuteObservable源碼
final class CallExecuteObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallExecuteObservable(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.
1. Call<T> call = originalCall.clone();
2. observer.onSubscribe(new CallDisposable(call));
3. boolean terminated = false;
4. try {
5. Response<T> response = call.execute();
if (!call.isCanceled()) {
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(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));
}
}
}
}
private static final class CallDisposable implements Disposable {
private final Call<?> call;
CallDisposable(Call<?> call) {
this.call = call;
}
@Override public void dispose() {
call.cancel();
}
@Override public boolean isDisposed() {
return call.isCanceled();
}
}
先看一下我標(biāo)記的第5行Response<T> response = call.execute();這行代碼就是執(zhí)行網(wǎng)絡(luò)請(qǐng)求了踩娘,至于call實(shí)例的具體實(shí)現(xiàn)方式稍后分析,目前您只需要知道這么多喉祭。
繼續(xù)分析該方法之前养渴,我們先回憶一下,還記得訂閱者NetRequestSubscriber中有個(gè)cancelRequest()方法嗎泛烙,調(diào)用了onSubscribe(@NonNull Disposable d)方法中傳入的Disposable對(duì)象的dispose()方法來(lái)取消網(wǎng)絡(luò)請(qǐng)求理卑,為什么這個(gè)方法能取消網(wǎng)絡(luò)請(qǐng)求呢?回答這個(gè)問(wèn)題要繼續(xù)看一下subscribeActual方法蔽氨∶赀耄看我標(biāo)記的第2行observer.onSubscribe(new CallDisposable(call))帆疟;CallDisposable是CallExecuteObservable定義的內(nèi)部類,實(shí)現(xiàn)了Disposable接口宇立,dispose()方法中調(diào)用了call.cancel()方法來(lái)取消網(wǎng)絡(luò)請(qǐng)求踪宠,是不是與NetRequestSubscriber中的取消請(qǐng)求方法對(duì)上號(hào)了~。
到此為止妈嘹,通過(guò)分析Retrofit實(shí)例柳琢、ApiService實(shí)例的構(gòu)建及RxJava2CallAdapterFactory源碼追蹤,我們已經(jīng)知道了網(wǎng)絡(luò)請(qǐng)求的執(zhí)行润脸、取消以及如何返回的Observable柬脸,之前提及的幾處重點(diǎn)已經(jīng)粗略了解大半。但是我們還不知道攔截器如何被觸發(fā)工作的毙驯。下面繼續(xù)分析一下call實(shí)例是如何實(shí)現(xiàn)的倒堕,call.execute()方法到底做了什么勾當(dāng),或許它與攔截器暗中勾結(jié)呢
回顧ApiService實(shí)例的構(gòu)建方法爆价,第18行
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); // 請(qǐng)留意okHttpCall
上面提及的call實(shí)例就是這個(gè)okHttpCall啦涩馆。沒(méi)辦法,只能再看一看OkHttpCall源碼了允坚,做一下簡(jiǎn)單了解魂那,打入OkHttpCall內(nèi)部,直接定位到execute()方法
@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 {
// 注釋1:繼續(xù)追蹤createRawCall()方法吧...
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
// 此處請(qǐng)關(guān)聯(lián)上述注釋1
return parseResponse(call.execute());
}
看過(guò)源碼很頭疼稠项,顯然我們還要繼續(xù)追蹤createRawCall()方法涯雅,繼續(xù)吧
1. private okhttp3.Call createRawCall() throws IOException {
2. Request request = serviceMethod.toRequest(args);
// 此處想哭
3. okhttp3.Call call = serviceMethod.callFactory.newCall(request);
4. if (call == null) {
5. throw new NullPointerException("Call.Factory returned null.");
6. }
7. return call;
8. }
代碼簡(jiǎn)潔明了,繼續(xù)調(diào)查第3行吧展运,如果您的記憶不算差活逆,應(yīng)該記得之前我們?yōu)榱藢ふ褻allAdapter簡(jiǎn)單分析過(guò)此serviceMethod的創(chuàng)建過(guò)程,現(xiàn)在它又回來(lái)了:我馬三立又回來(lái)了...
在ServiceMethod的構(gòu)造方法中拗胜,可以知道callFactory其實(shí)是Retrofit實(shí)例的callFactory蔗候,而Retrofit實(shí)例的callFactory是我們?cè)O(shè)置的OkHttpClient實(shí)例,如果您已經(jīng)沒(méi)有印象請(qǐng)返回查看埂软。好啦锈遥,直接看OkHttpClient的newwCall(Request request)方法,了解Call實(shí)例時(shí)如何創(chuàng)建的
@Override
public Call newCall(Request request) {
// 心中一萬(wàn)個(gè)草泥馬勘畔,又牽涉到RealCall這個(gè)類
return new RealCall(this, request, false /* for web socket */);
}
哎所灸,沒(méi)辦法,繼續(xù)查看RealCall這個(gè)類吧炫七,直接定位其execute()方法及相關(guān)聯(lián)方法
1. final class RealCall implements Call {
2. @Override
3. public Response execute() throws IOException {
4. synchronized (this) {
5. if (executed) throw new IllegalStateException("Already Executed");
6. executed = true;
7. }
8. captureCallStackTrace();
9. try {
10. client.dispatcher().executed(this);
11. Response result = getResponseWithInterceptorChain();
12. if (result == null) throw new IOException("Canceled");
13. return result;
14. } finally {
15. client.dispatcher().finished(this);
16. }
17. }
18. Response getResponseWithInterceptorChain() throws IOException {
19. // Build a full stack of interceptors.
20. List<Interceptor> interceptors = new ArrayList<>();
21. interceptors.addAll(client.interceptors()); // 我們?cè)O(shè)置的攔截器爬立,處于列表第一位
// 以下幾個(gè)為內(nèi)置攔截器
22. interceptors.add(retryAndFollowUpInterceptor);
23. interceptors.add(new BridgeInterceptor(client.cookieJar()));
24. interceptors.add(new CacheInterceptor(client.internalCache()));
25. interceptors.add(new ConnectInterceptor(client));
26. if (!forWebSocket) {
27. interceptors.addAll(client.networkInterceptors());
28. }
29. interceptors.add(new CallServerInterceptor(forWebSocket));
// 注意此處傳入的index參數(shù)為0,攔截器列表也被傳入RealInterceptorChain構(gòu)造方法
30. Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);
31. return chain.proceed(originalRequest);
32. }
33. }
看一下第11行代碼万哪,執(zhí)行這行代碼獲取網(wǎng)絡(luò)請(qǐng)求響應(yīng)數(shù)據(jù)侠驯,但是仍然看不出攔截器是如何起作用的抡秆,但是請(qǐng)注意注釋部分,追擊getResponseWithInterceptorChain()方法試試吟策±旁看第31行代碼:執(zhí)行chain.proceed(originalRequest)獲取的響應(yīng)數(shù)據(jù),硬著頭皮看看chain是什么鬼踊挠。定位到第30行乍桂,查閱一下RealInterceptorChain構(gòu)造方法及proceed方法
1. public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection, int index, Request request) {
2. this.interceptors = interceptors;
3. this.connection = connection;
4. this.streamAllocation = streamAllocation;
5. this.httpCodec = httpCodec;
6. // 上一步傳入此處的index為0
7. this.index = index;
8. this.request = request;
9. }
10. public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException {
11. if (index >= interceptors.size()) throw new AssertionError();
12. calls++;
13. // If we already have a stream, confirm that the incoming request will use it.
14. if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
15. throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
16. }
17. // If we already have a stream, confirm that this is the only call to chain.proceed().
18. if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
19 }
20. // Call the next interceptor in the chain.
21. RealInterceptorChain next = new RealInterceptorChain( interceptors, streamAllocation, httpCodec, connection, index + 1, request);
// 上一步傳入的index 為0,因此取我們?cè)O(shè)置的攔截器
22. Interceptor interceptor = interceptors.get(index);
23. Response response = interceptor.intercept(next);
24. // Confirm that the next interceptor made its required call to chain.proceed().
25. if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
26. }
27. // Confirm that the intercepted response isn't null.
28. if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
29. }
30. return response;
31. }
定位到第22行效床,終于看到了攔截器睹酌,取index為0,所以取第一個(gè)剩檀,就是我們?cè)O(shè)置的攔截器了憋沿;再看第23行,執(zhí)行interceptor.intercept(next)攔截請(qǐng)求。攔截器觸發(fā)流程解析就此終結(jié)沪猴,至于攔截器的用法請(qǐng)參考Retrofit Interceptor(攔截器) 攔截請(qǐng)求并做相關(guān)處理
到此為止辐啄,我們已經(jīng)梳理了網(wǎng)絡(luò)請(qǐng)求大致流程,我們做的配置也做了解析运嗜,本文也到此結(jié)束