天天看點

【GT-安卓應用開發之Retrofit+RxJava網絡請求】

前言:今天記錄一下最近使用比較多的一個網絡請求架構,也就是今天的主角Retrofit+RxJava。對于RxJava其實就是對異步操作的封裝,對于它的評價優劣參半(本人對其的态度比較中立,這也可以與本人的理念相關,我是一個注重結果的人,使用什麼架構對我來說并不是很緊要)。而Retrofit是什麼呢?它其實是對OkHttp進一步的封裝,實質上還是由OkHttp完成網絡的請求加載。既然這樣為什麼還要選擇Retrofit呢?其實對于我個人而言還是無所謂,隻要能完成需求直接用OkHttp甚至用最原始的那幾種都是可以的。不好意思。。。有點跑題了!Retrofit是對網絡請求接口進行了封裝,這不僅便于我們的接口調用,也使得代碼更加美觀。

        廢話說了一堆,現在開始體驗一下吧。

        Step1,添加依賴

        我們需要添加RxJava、OkHttp以及Retrofit的依賴

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:[email protected]'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okio:okio:1.9.0'      

        Step2,建立接口

        我們建立一個名為Api的接口檔案,并定義相關的接口。我們需要提前了解Retrofit的一些注解,大家可以上網搜尋“Retrofit注解”,相關的文章是很多的。代碼如下:

public interface Api {
    //好友清單
    @FormUrlEncoded
    @POST("api/talk/class_user_list")
    Call<ResponseBody> getFriends(@Field("classid") String classid);
}      

       Step3,建立Retrifit對象RetrofitBean

       直接貼代碼了,相關的解釋都在注釋裡面

public class RetrofitBean {
    private static Api api;
    public static Api getApi(){
        api = null;
        OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
        //初始化retrofit架構
        Retrofit build = new Retrofit.Builder()
                .client(okHttpBuilder.build())
                //1.配置主機位址
                .baseUrl(com.example.administrator.retrofitdemo.Retrofit.HttpUrl.BASE_URLAPI)
                //2.解析json的工具
                .addConverterFactory(GsonConverterFactory.create(new Gson())).build();

        //讀取接口上面的參數
        api = build.create(Api.class);
        return api;
    }
}      

        Step4,調用接口

        我們定義一個getFriend方法請求資料,并将取到的資料渲染到界面

public void getFirend() {
    Call<ResponseBody> data = RetrofitBean.getApi().getFriends("4");
    retrofit2.Callback<ResponseBody> callback = new retrofit2.Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            try {
                tv.setText(response.body().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {

        }
    };
    data.enqueue(callback);
}      

        上面幾步就是該架構的簡單用法,雖然能完成我們的基本需求,但是存在一些bug會造成不好的使用者體驗,且無法完美滿足我們的真實需求。下面就介紹我遇到過的幾個問題和我的解決方案。

        1、連續請求。

         最初的時候,我是一個Activity中定義一個Call對象,但是會出現這麼一種情況,當這個Activity中需要多個接口或者需要連續請求多次接口的時候,經常會出現資料錯亂或者應用崩掉的現象。剛遇到這種問題的時候,我理索然的認為是網絡不穩定的原因,可是我發現經常會出現這種問題,就決定深入排查一下問題。從網上查閱資料,最後發現有兩種方法解決,一個是改成同步請求(這種方式不能在主線程中使用并且效率較低,不采用);第二種方法就是每次請求的時候重新定義一個Call對象。

        2、請求為完成。

        有時候,目前Activity請求未完成便退出并重新打開一個新的會請求網絡的Activity會出現應用崩掉。這就需要我們及時取消掉未完成的請求,我們可以利用call.cancel();完成取消請求。

        3、response.body().string()不能重複使用

        在一個回調中該方法隻可以調用一次,再次調用傳回的則是null對象。但是實際應用中,我們需要多次用到這個結果,那麼我們便定義一個String對象,之後直接操作String對象即可,