哪個(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è)Retrofit和Retrofit怎么去保存等問題,本人思路是創(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ā)愉快!
