1.Retrofit基本用法
1.初始化
webInterface = new Retrofit.Builder()
.baseUrl(hostname)
.client(client)//这个client是OkHttpClient,以后和Okhttp的基本用法和流程分析中细说
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.build()
.create(WebInterface.class);
2.定义网络接口
public interface WebInterface {
@POST("/***/index")
Observable getHomeIndex(@Body BaseRequest request);//首页
@FormUrlEncoded
@POST("/***/freecall")
Observable freeCall(@Field("phone") String phone);//免费电话
}
3.在Activity中调用
dataWork = WebHelper.getWebInterface()
.getHomeIndex(request)
.compose(new WebTransformer<>(this))
.subscribe(new WebSubscriber() {
@Override
public void onSuccess(IndexResponse response) {
parseData(response);
}
});
注意要在onDestroy中解绑:
@Override
public void onDestroy() {
super.onDestroy();
if (dataWork != null) {
dataWork.isUnsubscribed();
}
}
4.在WebTransformer中添加进度条和线程切换
public class WebTransformer implements Observable.Transformer {
Context context;
boolean hasDialog = true;
public WebTransformer(Context context) {
this.context = context;
}
public WebTransformer(Context context, boolean hasDialog) {
this.context = context;
this.hasDialog = hasDialog;
}
@Override
public Observable call(Observable observable) {
return observable.subscribeOn(Schedulers.io())
.doOnSubscribe(new Action0() {
@Override
public void call() {
if (hasDialog) {
DialogHelper.showDialog(context);
}
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread());
}
}
5.在WebSubscriber中添加统一的错误处理
public abstract class WebSubscriber extends Subscriber {
@Override
public void onCompleted() {
}
@Override
public void onNext(T t) {
DialogHelper.hideDialog();
//居然还有的返回值不是继承BaseResponse,我想杀了后台,别拦我
if (t instanceof BaseResponse) {
BaseResponse baseResponse = (BaseResponse) t;
//不要问我为什么这么多code,我也不知道后台怎么想的
if (baseResponse.getCode() != 0 || baseResponse.getResultCode() != 0 || baseResponse.getReplyCode() != 0) {
String tip = "";
//不要问我为什么这么多message,我也不知道后台怎么想的
if (!TextUtils.isEmpty(baseResponse.getMessage())) {
tip = baseResponse.getMessage();
} else {
tip = baseResponse.getRemark();
}
ToastHelper.show(tip);
onFailed(t);
} else {
onSuccess(t);
}
} else {
onSuccess(t);
}
}
@Override
public void onError(Throwable e) {
DialogHelper.hideDialog();
if (e instanceof HttpException) {
ToastHelper.show("网络异常");
HttpException exception = (HttpException) e;
if (exception.code() == 404) {
//没登陆的时候居然返回404,我想杀了后台,别拦我
SkipManager.gotoLogin();
}
}
}
//需要个性化的错误处理时,重写它
protected void onFailed(T t) {
}
//正确的回调
public abstract void onSuccess(T t);
}
2.Retrofit的优点
Q1.什么是网络框架?
业务层-->网络调度层-->网络执行层
这里:
Retrofit是网络调度层
类似volley, retrofit, android-async-http
做具体业务请求、线程切换、数据转换
OkHttp是网络执行层
类似HttpClient, HttpUrlConnection
做底层网络请求
Q2.为什么用Retrofit?
因为Retrofit有:
CallAdapter-请求适配器:
可以实现多种请求响应形式:同步方式、异步回调方式、RxJava方式
Converter-数据转换器:
可以自己定义responseBodyConverter和requestBodyConverter,实现加密功能和各种奇葩格式的解析
3.Retrofit流程分析
以下分析基于compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
1.先看我们初始化时的Retrofit.create()方法
这里用到了动态代理,忘记了的话,可以先看我的博客: Java-动态代理
2.通过loadMethodHandler(),创建了MethodHandler
3.进去看下MethodHandler.create()
4.在MethodHandler.create()方法中,创建了CallAdapter
5.在MethodHandler.create()方法中,创建了responseConverter和requestFactory,在parse()中解析了注解信息
6.回到Retrofit类,看invoke()方法,
adapte()方法只是一个抽象方法
7.CallAdapter有多种实现,为简单起见,只看ExecutorCallAdapterFactory中对adapter的实现
8.在ExecutorCallbackCall.enqueue()方法中,
9.delegate.enqueue()是一个抽象方法
实现在OkhttpCall.queue()中,方法太长,截图没截完
继续看OkhttpCall.enqueue()方法,这里就是具体执行网络请求的地方,将Okhttp.Callback转换成了一个Retrofit.Callback
为什么有两种Callback?因为一个是网络执行层的Callback,一个是网络调度层的Callback
10.这里是如何创建Request的呢?看rawCall的创建方法,通过requestFactory将args转成Request,通过callFactory将request转成Okhttp3.Call
为什么有两种Call?因为一个是网络执行层的Call,一个是网络调度层的Call
11.好了,发起网络请求搞定,然后网络响应值是如何解析的呢?
看onRespone回调中的parseResponse()
12.点进蓝色的responseConverter.convert(catchingBody)
又是接口,实现在这:
好了,流程分析已经大致搞定了,不过这里通过requestBodyConverter用注解创建Requestbody的过程,还是没找到调用的地方,以后再来找下。
参考目录
- Retrofit分析-漂亮的解耦套路
- OkHttp, Retrofit, Volley应该选择哪一个?