[英]Creating custom network listner for Retrofit Kotlin Coroutine
我正在使用改裝服務而不使用回調。 因此,它可能與 Kotlin Coroutine suspend fun
一起使用。 我參考了許多博客、媒體和許多教程。 好吧,使用協程scope
和IO and Main
線程很容易得到響應。
所以,在參考了一些例子之后,我考慮做這樣的代碼:
改造服務接口RetrofitInterfaces.kt
:
interface RetrofitInterfaces {
@FormUrlEncoded
@POST("get-videos-pagination")
suspend fun getTemplates(@Field("app_name") app_name: String,
@Field("sort_by") sortBy: String,
@Field("video_loaded_ids") loadedIds: String): Response<Model_Video_List>
}
其中Model_Video_List.kt
class 是我的響應數據 class。
Retrofit 生成器RetrofitClient.kt
:
object RetrofitClient {
fun makeRetrofitService(mContext: Context): RetrofitInterfaces {
val gson = GsonBuilder().setLenient().create()
return Retrofit.Builder()
.baseUrl(AppPreferences.getBaseUrl(mContext) + "/api/v3/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build().create(RetrofitInterfaces::class.java)
}
}
在這里,我使用Gson
serialise
或deserialise
化Json data
。
現在有什么問題以及問題從哪里開始得到錯誤響應我正在使用ResultWrapper.kt
:
class ResultWrapper {
enum class ErrorCode {
NETWORK,// Connection failed or timeout
SERVER,// Server errors due to maintenance or over request
INVALID// Response is success but can't serialised with Data Class!
}
interface ResponseWrapper {
suspend fun onSuccess(response: Response<Any>)
suspend fun onFailure(eCode: ErrorCode)
}
private var responseWrapper: ResponseWrapper? = null
set
suspend fun enqueue(response: Response<Any>, responseWrapper: ResponseWrapper) {
this.responseWrapper = responseWrapper
if (response.isSuccessful) {
responseWrapper.onSuccess(response)
} else {
val errorCode = response.code()
when (errorCode) {
in 200..299 -> {
responseWrapper.onFailure(ErrorCode.INVALID)
}
in 400..499 -> {
responseWrapper.onFailure(ErrorCode.NETWORK)
}
in 500..599 -> {
responseWrapper.onFailure(ErrorCode.SERVER)
}
}
}
}
}
所以,現在我可以在app
的任何地方調用這個enqueue fun
,比如:
private fun getVideoList(loadedIds: String, sortBy: String) {
val service = RetrofitClient.makeRetrofitService(mContext)
scope.launch {
val response = service.getTemplates("MyApp", sortBy, loadedIds)
val resultWrapper = ResultWrapper()
resultWrapper.enqueue(response, object : ResultWrapper.ResponseWrapper {
override suspend fun onSuccess(response: Response<Any>) {
}
override suspend fun onFailure(eCode: ResultWrapper.ErrorCode) {
}
})
}
}
但是我在resultWrapper.enqueue()
中傳遞response
時遇到compile error
,因為在ResultWrapper.ResponseWrapper interface
中,有一個用suspend fun onSuccess(response: Response<Any>)
定義的方法。 所以,這里出現了類型轉換問題!
如果 Retrofit CallBack<T>
可以處理任何類型的Model or Data classes
並返回精確的類型。 像上面的服務需要Model_Video_List
class 來響應,其他服務需要有自己的那該怎么辦呢? 是否有唯一的方法為每個服務使用單獨的 function? 還是只有在 Java 中才有可能?!
您可以在 class ResultWrapper
中引入通用參數類型T
,因此每當您創建此 class 的實例時,您必須指定一個實際類型來代替T
。
將您的ResultWrapper
更改為:
class ResultWrapper<T> {
enum class ErrorCode {
NETWORK,// Connection failed or timeout
SERVER,// Server errors due to maintenance or over request
INVALID// Response is success but can't serialised with Data Class!
}
interface ResponseWrapper<T> {
suspend fun onSuccess(response: Response<T>)
suspend fun onFailure(eCode: ErrorCode)
}
private var responseWrapper: ResponseWrapper<T>? = null
set
suspend fun enqueue(response: Response<T>, responseWrapper: ResponseWrapper<T>) {
this.responseWrapper = responseWrapper
if (response.isSuccessful) {
responseWrapper.onSuccess(response)
} else {
val errorCode = response.code()
when (errorCode) {
in 200..299 -> {
responseWrapper.onFailure(ErrorCode.INVALID)
}
in 400..499 -> {
responseWrapper.onFailure(ErrorCode.NETWORK)
}
in 500..599 -> {
responseWrapper.onFailure(ErrorCode.SERVER)
}
}
}
}
}
並將您的方法更改為:
private fun getVideoList(loadedIds: String, sortBy: String) {
val service = RetrofitClient.makeRetrofitService(mContext)
scope.launch {
val response = service.getTemplates("MyApp", sortBy, loadedIds)
val resultWrapper = ResultWrapper<Model_Video_List>()
resultWrapper.enqueue(response, object : ResultWrapper.ResponseWrapper<Model_Video_List> {
override suspend fun onSuccess(response: Response<Model_Video_List>) {
}
override suspend fun onFailure(eCode: ResultWrapper.ErrorCode) {
}
})
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.