1. 程式人生 > >Retrofit基本用法和流程分析

Retrofit基本用法和流程分析

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<HomeResponse> getHomeIndex(@Body BaseRequest request);//首頁

    @FormUrlEncoded
    @POST("/***/freecall")
    Observable<BaseResponse> freeCall(@Field("phone") String phone);//免費電話

}

3.在Activity中呼叫

        dataWork = WebHelper.getWebInterface()
                .getHomeIndex(request)
                .compose(new WebTransformer<>(this))
                .subscribe(new WebSubscriber<IndexResponse>() {
                    @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<T> implements Observable.Transformer<T, T> {
    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<T> call(Observable<T> 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<T> extends Subscriber<T> {

    @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的實現


Paste_Image.png

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的過程,還是沒找到呼叫的地方,以後再來找下。