之前分享出來的RxJava2+Retrofit2實(shí)現(xiàn)網(wǎng)絡(luò)請求封裝在新的項(xiàng)目中使用良好沒有出現(xiàn)什么水土不服的情況。好久沒有更新簡書了,最近到了新公司忙的昏天暗地的.乘著產(chǎn)品迭代的中間期,學(xué)習(xí)kotlin的使用,也把之前的網(wǎng)絡(luò)請求框架轉(zhuǎn)換成了kotlin語言.現(xiàn)在將代碼分享出來 https://github.com/timordu/Rely-kotlin ,對比以前的java的框架,kotlin語言的框架使用起來更簡單。現(xiàn)就新的特性介紹如下
構(gòu)建請求
在kotlin版本中使用了建造者模式,通過HttpBuilder
類來獲取Retrofit
對象,具體使用如下
interface ApiService {
companion object Factory {
fun auth(): ApiService {
val httpBuilder = HttpBuilder()
.baseUrl("http://192.168.2.111:8080/JNCApp/")
// .addHeader("","")
// .addHeaders(ArrayMap())
// .addParam("","")
// .addParams(ArrayMap())
// .addInterceptor()
// .addNetworkInterceptor()
.build()
return httpBuilder.create(ApiService::class.java)
}
fun default(): ApiService {
val dir = Environment.getExternalStorageDirectory()
val file = File(dir.absoluteFile, "Rely")
if (!file.exists()) file.mkdirs()
val httpBuilder = HttpBuilder()
.baseUrl("http://192.168.2.111:8080/JNCApp/")
.addHeaders(ShareData.getHeaders())
.setCacheFile(file)
.build()
return httpBuilder.create(ApiService::class.java)
}
}
//@Headers("Cache-Control: public, max-age=600")//只緩存get請求
/**
* 刷新token
*/
@FormUrlEncoded
@POST("login/refreshToken.action")
fun refreshToken(@Field("refreshToken") refreshToken: String): Call<String>
@FormUrlEncoded
@POST("login/login.action")
@Headers("Cache-Control: public, max-age=600")
fun login(@Field("user_id") account: String,
@Field("passwd") passport: String): Observable<Result<Account>>
@FormUrlEncoded
@POST("login/login.action")
fun login2(@Field("user_id") account: String,
@Field("passwd") passport: String): Call<Result<Account>>
}
該接口類主要是用來聲明接口的,和之前的使用方式一樣,唯一不同的是增加了伴生對象,在此可以建立多個方法以滿足不同請求地址和請求參數(shù)的配置。在使用的時候也有所簡化,比如上面我們調(diào)用登錄的接口可以直接使用ApiService.auth().login()
。
生命周期
在java版本中,我們創(chuàng)建了RxUtil
對象來簡化請求和綁定生命周期,在kotlin版本中,代碼有所簡化,這此使用了擴(kuò)展函數(shù),暫時只支持跟隨Activity和Fragment的生命周期,無法綁定到具體的生命周期,后期補(bǔ)充。
/*
* 綁定生命周期和彈窗
*/
fun <T> applySchedulers(provider: LifecycleProvider<*>, dialog: Dialog): ObservableTransformer<T, T> {
return ObservableTransformer<T, T> {
upstream ->
upstream
.delay(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.doOnSubscribe({ disposable ->
dialog.setOnCancelListener { disposable.dispose() }
dialog.show()
})
.observeOn(AndroidSchedulers.mainThread())
.doOnTerminate { dialog.dismiss() }
.bindToLifecycle(provider)
}
}
/*
* 綁定生命周期和無彈窗
*/
fun <T> applySchedulers(provider: LifecycleProvider<*>): ObservableTransformer<T, T> {
return ObservableTransformer<T, T> {
upstream ->
upstream
.delay(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.bindToLifecycle(provider)
}
}
/*
* 不綁定生命周期和無彈窗,針對Service中的請求使用
*/
fun <T> applySchedulers(): ObservableTransformer<T, T> {
return ObservableTransformer<T, T> {
upstream ->
upstream
.delay(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
利用kotlin的擴(kuò)展函數(shù)的屬性可以優(yōu)化成
fun <T> Observable<T>.applySchedulers(provider: LifecycleProvider<*>, dialog: Dialog?, delay: Long = 1): Observable<T> {
return delay(delay, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.doOnSubscribe { disposable ->
dialog?.setOnCancelListener { disposable.dispose() }
dialog?.show()
}
.observeOn(AndroidSchedulers.mainThread())
.doOnTerminate { dialog?.dismiss() }
.bindToLifecycle(provider)
}
fun <T> Observable<T>.applySchedulers(provider: LifecycleProvider<*>): Observable<T> {
return subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.bindToLifecycle(provider)
}
fun <T> Observable<T>.applySchedulers(): Observable<T> {
return subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
優(yōu)化后的網(wǎng)絡(luò)請求相比之前的寫法又簡化了不少.
ApiService.getUser().login("","") .applySchedulers() .subscribe(...)
請求重試
在java版本中,請求失敗重試時配置在RxUtil
類中的,為了讓請求重試的參數(shù)可配置,所以新建了RetryInterceptor
,在配置okhttpBuilder
添加了攔截器,以達(dá)到同樣的效果。具體代碼如下
class RetryInterceptor(private var retryCount: Int, private var retryDelay: Int) : Interceptor {
private var currentRetry = 0
override fun intercept(chain: Interceptor.Chain): Response {
var response = chain.proceed(chain.request())
while (!response.isSuccessful && currentRetry < retryCount) {
currentRetry++
Thread.sleep(retryDelay * 1000L)
response = chain.proceed(chain.request())
}
return response
}
}
總結(jié)
以上就是kotlin版本RxJava2+Retrofit2的網(wǎng)絡(luò)請求框架,后續(xù)有新的想法將繼續(xù)補(bǔ)充