Retrofit運(yùn)行時(shí)動(dòng)態(tài)改變BaseUrl解決方案

哪個(gè)小可愛在偷偷的看我~~


偷瞄.gif
背景

Android正式項(xiàng)目中可能會(huì)涉及到多個(gè)BaseUrl,使用Retrofit開發(fā)者可能會(huì)遇到多BaseUrl不是很好處理情況,下面給大家介紹倆種Retrofit動(dòng)態(tài)設(shè)置BaseUrl方法,以便大家不時(shí)之需

第一種方案

簡(jiǎn)單粗暴解決方案,利用Retrofit請(qǐng)求優(yōu)先級(jí),因?yàn)?code>Retrofit支持全路徑,比如

 @GET("http://www.baidu.com")
 Observable<Object> getApi(@Path("param") String param);
第二種方案

Retrofit默認(rèn)只能設(shè)置一個(gè)BaseUrl,沒有提供其Api去修改,所以我們只能通過其他方案去實(shí)現(xiàn),網(wǎng)上也有很多介紹的,但嘗試用了下感覺很不理想,于是自己稍加封裝了下,思路其實(shí)簡(jiǎn)單。

思路:一個(gè)Retrofit只能設(shè)置一個(gè)BaseUrl,這樣我們可以創(chuàng)建多個(gè)Retrofit不就可以了嗎?但如果一個(gè)請(qǐng)求創(chuàng)建一個(gè)Retrofit必然是不理想的,所以我們可以有幾個(gè)BaseUrl創(chuàng)建幾個(gè),有人會(huì)說這樣不會(huì)造成內(nèi)存的開銷嗎?答案是不會(huì)的,一個(gè)項(xiàng)目中也不會(huì)出現(xiàn)N多個(gè)BaseUrl,所以這點(diǎn)開銷不用過于糾結(jié)

代碼實(shí)現(xiàn):在代碼設(shè)計(jì)時(shí)可以盡可能去優(yōu)化,所以當(dāng)我們用到此BaseUrl時(shí),再去創(chuàng)建,用不到不創(chuàng)建,這樣便會(huì)出現(xiàn)個(gè)問題,怎樣知道我應(yīng)該使用哪個(gè)RetrofitRetrofit怎么去保存等問題,本人思路是創(chuàng)建成功便添加到集合緩存下載,使用的時(shí)候去比對(duì)集合中BaseUrl和當(dāng)前是否匹配,如果一致從集合中獲取,如果不一致去創(chuàng)建新的,如果使用沒有傳入BaseUrl便用默認(rèn)的,最基本的判斷,實(shí)現(xiàn)代碼如下

1、正常創(chuàng)建Retrofit
public class ApiRetrofit {

    private static ApiRetrofit mApiRetrofit;
    private Retrofit retrofit;
    private ApiServer apiServer;
    public static String mBaseUrl = BaseContent.baseUrl;

    public ApiRetrofit() {
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true);//錯(cuò)誤重聯(lián)
        retrofit = new Retrofit.Builder()
                .baseUrl(mBaseUrl )
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(httpClientBuilder.build())
                .build();

        apiServer = retrofit.create(ApiServer.class);
    }

    public static ApiRetrofit getInstance() {
        if (mApiRetrofit == null) {
            synchronized (Object.class) {
                if (mApiRetrofit == null) {
                    mApiRetrofit = new ApiRetrofit();
                }
            }
        }
        return mApiRetrofit;
    }
}
2、對(duì)創(chuàng)建Retrofit稍加封裝,已適應(yīng)我們的需求

新建保存對(duì)象的集合

private static List<Retrofit> mRetrofitList = new ArrayList<>();
private static List<ApiRetrofit> mApiRetrofitList = new ArrayList<>();

修改創(chuàng)建時(shí)候的邏輯,如果請(qǐng)求接口時(shí)傳入BaseUrl,檢測(cè)BaseUrl是否為空,如果為空使用默認(rèn)接口,如果不為空,再?gòu)木彺娴?code>Retrofit中查找是否已經(jīng)才創(chuàng)建過了,如果創(chuàng)建了用緩存的,如果沒有創(chuàng)建則創(chuàng)建

注:這塊可以用正則檢查下傳入的url是否為正規(guī)的域名,再做下判斷

//創(chuàng)建Retrofit代碼中加入
 apiServer = retrofit.create(ApiServer.class);
 mRetrofitList.add(retrofit);

public static ApiRetrofit getInstance() {
        mBaseUrl = BaseContent.baseUrl;

        int mIndex = -1;
        for (int i = 0; i < mRetrofitList.size(); i++) {
            if (BaseContent.baseUrl.equals(mRetrofitList.get(i).baseUrl().toString())) {
                mIndex = i;
                break;
            }
        }

        //新的baseUrl
        if (mIndex == -1) {
            synchronized (Object.class) {
                mApiRetrofit = new ApiRetrofit();
                mApiRetrofitList.add(mApiRetrofit);
                return mApiRetrofit;
            }
        } else {
            //以前已經(jīng)創(chuàng)建過的baseUrl
            return mApiRetrofitList.get(mIndex);
        }
    }


    public static ApiRetrofit getInstance(String baseUrl) {
        if (!TextUtils.isEmpty(baseUrl)) {
            mBaseUrl = baseUrl;
        } else {
            mBaseUrl = BaseContent.baseUrl;
        }

        int mIndex = -1;
        for (int i = 0; i < mRetrofitList.size(); i++) {
            if (baseUrl.equals(mRetrofitList.get(i).baseUrl().toString())) {
                mIndex = i;
                break;
            }
        }

        //新的baseUrl
        if (mIndex == -1) {
            synchronized (Object.class) {
                mApiRetrofit = new ApiRetrofit();
                mApiRetrofitList.add(mApiRetrofit);
                return mApiRetrofit;
            }
        } else {
            //以前已經(jīng)創(chuàng)建過的baseUrl
            return mApiRetrofitList.get(mIndex);
        }
    }
3、使用時(shí)寫法

地址可以寫成常量,不要我這樣寫,寫成常量判斷準(zhǔn)確

ApiRetrofit.getInstance("http://www.baidu.com/").getApiService().getCeShi(params)


最后祝大家開發(fā)愉快!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容