詳解Android項目多服務(wù)端接口適配(超簡單)
現(xiàn)狀
Android項目如果是多服務(wù)端接口時,一般怎么弄呢?
方法1:服務(wù)器地址放在Header中
把服務(wù)器地址放在接口Header中,然后通過攔截器來動態(tài)修改請求地址而實現(xiàn)的。除了默認服務(wù)器的接口,其它都要加一個Header,有點麻煩。看起來也不爽,不簡潔。
interface ApiHeaderCase {
/************************** server A ****************************/
@Headers("host:$SERVER_HOST_A")
@GET("user/loginWithScanCode")
fun aMethod1(@Query("id") id: Int): Observable<ResponseBody>
/************************** server B ****************************/
@Headers("host:$SERVER_HOST_B")
@GET("user/loginWithScanCode")
fun bMethod1(@Query("id") id: Int): Observable<ResponseBody>
}
方法2:多套服務(wù)類,實例化為多個對象,準確查找接口歸屬服務(wù)
定義多個類,每個類定義一套服務(wù)接口。然后分別實例化為多個對象,再使用準確的對象來調(diào)用接口。這種方法運行效率是最高的,但是在開發(fā)時,可能無法快速知道接口歸屬與哪個服務(wù),需要查看代碼才能準確知曉,可以說是少了代碼提示能力。
interface ApiA {
@GET("user/loginWithScanCode")
fun methodA(@Query("id") id: Int): Observable<ResponseBody>
}
interface ApiB {
@GET("user/loginWithScanCode")
fun methodB(@Query("id") id: Int): Observable<ResponseBody>
}
方法3:全寫在一起,實例化為多個對象,準確調(diào)用方法
把所有接口都寫在一個類中,然后根據(jù)服務(wù)地址分別實例化為多個對象。再準確調(diào)用方法,為了保證準確調(diào)用方法,可以給每個接口加個服務(wù)名的前綴,以減少方法調(diào)錯的問題。
interface ApiAllInOne {
/************************** server A ****************************/
@GET("user/loginWithScanCode")
fun aMethod1(@Query("id") id: Int): Observable<ResponseBody>
/************************** server B ****************************/
@GET("user/loginWithScanCode")
fun bMethod1(@Query("id") id: Int): Observable<ResponseBody>
}
const val SERVER_HOST_A = "https://www.a.com/"
const val SERVER_HOST_B = "https://www.b.com/"
fun getApi(retrofit: Retrofit, host: String): ApiAllInOne {
return retrofit.newBuilder()
.baseUrl(host).build()
.create(ApiAllInOne::class.java)
}
fun showNomalUseCase(retrofit: Retrofit) {
val apiA = getApi(retrofit, SERVER_HOST_A)//save as single instance for repeated usage
apiA.aMethod1(1).subscribe()
apiA.bMethod1(1).subscribe()//invalid usage, but no compile error
val apiB = getApi(retrofit, SERVER_HOST_B)
apiB.bMethod1(1).subscribe()
apiB.aMethod1(1).subscribe()//invalid usage, but no compile error
}
有更簡單的方法嗎?
當然有了,而且超方便!
定義接口
(建議)在一個KT文件中定義所有接口,方便查找和維護。
interface ApiHolder : ApiA, ApiB
@BaseUrl("https://www.a.com/")
interface ApiA {
@GET("user/loginWithScanCode")
fun methodA(@Query("id") id: Int): Observable<ResponseBody>
}
@BaseUrl("https://www.b.com/")
interface ApiB {
@GET("user/loginWithScanCode")
fun methodB(@Query("id") id: Int): Observable<ResponseBody>
}
建工具類
一般都需要個工具類的,方便配置攔截器等。如果沒有自定義的需求,也可以直接實例化來用。
可以重寫invokeApi方法,全局給每個Observable設(shè)定線程。
class ApiUtil : ApiHolderUtil<ApiHolder>(ApiHolder::class) {
companion object {
val apiUtil = ApiUtil()
val api = apiUtil.api
}
override fun invokeApi(api: Any, method: Method, args: Array<*>?): Any {
val observable = super.invokeApi(api, method, args) as Observable<*>
return observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
動態(tài)更新服務(wù)地址
還可以動態(tài)更新服務(wù)地址,比如實現(xiàn)測試服務(wù)和正式服務(wù)間切換。
//update api baseUrl when needed apiUtil.updateApi(ApiA::class, https://www.a2.com/)
調(diào)用接口
api.methodA(1).subscribe() api.methodB(1).subscribe()
引入依賴
dependencies {
implementation 'com.github.DonaldDu:ApiHolder:x.x.x'//JitPack version
}
該項目使用的三方庫
- OkHttp3
- Retrofit2
- rxjava3(可以修改為rxjava2)
api 'com.squareup.okhttp3:okhttp:4.7.2' api "com.squareup.retrofit2:retrofit:2.9.0" api "com.squareup.retrofit2:converter-gson:2.9.0" api "com.squareup.retrofit2:adapter-rxjava3:2.9.0" api 'io.reactivex.rxjava3:rxandroid:3.0.0'
其它說明
rxjava3 ->rxjava2
可以根據(jù)需要調(diào)整為rxjava2,建議用最新的。
//重寫ApiHolderUtil如下方法,RxJava3CallAdapterFactory ->RxJava2CallAdapterFactory即可。
protected open fun getRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.validateEagerly(validateEagerly)
.addConverterFactory(getGsonConverterFactory())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.baseUrl("http://www.demo.com/")
.client(client)
.build()
}
Timeout
可以給每套服務(wù)設(shè)置不同的超時
@BaseUrl("https://www.b.com/")
@Timeout(read = 100, timeUnit = TimeUnit.SECONDS)
interface ApiB {
@GET("user/loginWithScanCode")
fun methodB(@Query("id") id: Int): Observable<ResponseBody>
}
到此這篇關(guān)于詳解Android項目多服務(wù)端接口適配(超簡單)的文章就介紹到這了,更多相關(guān)Android多服務(wù)端接口適配 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 優(yōu)化之卡頓優(yōu)化的實現(xiàn)
這篇文章主要介紹了Android 優(yōu)化之卡頓優(yōu)化的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Flutter 實現(xiàn)網(wǎng)易云音樂字幕的代碼
這篇文章主要介紹了Flutter 實現(xiàn)網(wǎng)易云音樂字幕的代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
Android開發(fā)系列二之窗口Activity的生命周期
這篇文章主要介紹了Android學(xué)習系列二之窗口Activity的生命周期的相關(guān)資料,需要的朋友可以參考下2016-05-05
Android實現(xiàn)bitmap指定區(qū)域滑動截取功能
這篇文章主要為大家詳細介紹了Android實現(xiàn)bitmap指定區(qū)域滑動截取功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Android中一個應(yīng)用實現(xiàn)多個圖標的幾種方式
這篇文章主要給大家介紹了在Android中一個應(yīng)用如何實現(xiàn)多個圖標的幾種方式,其中包括了多Activity + intent-filter方式、activity-alias方式以及網(wǎng)頁標簽-添加快捷方式,分別給出了詳細的示例代碼,需要的朋友可以參考借鑒。2017-05-05
Android使用AudioRecord實現(xiàn)錄音功能
這篇文章主要為大家詳細介紹了Android使用AudioRecord實現(xiàn)錄音功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08

