问题描述
我正在使用改装服务,而没有使用回调.因此,它可能与Kotlin Coroutine的悬浮乐趣
一起使用.我提到了许多博客,媒体和许多教程.好吧,这很容易使用协程 scope
和 IO和Main
线程来获得响应.
I am using retofit service without using callback. So, its probably going with Kotlin Coroutine suspend fun
. I referred many blogs, mediums and so many tutorials. Well this is easy to get response using coroutine scope
with IO and Main
thread.
因此,在参考了一些示例之后,我考虑执行以下代码:
So, after referring some examples I am considers to do code like this:
Restrofit服务界面 RetrofitInterfaces.kt
:
Restrofit Service Interface 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
类是我的响应数据类.
Where Model_Video_List.kt
class is my response data class.
Retrofit Builder RetrofitClient.kt
:
Retrofit Builder 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数据
.
Here I am using Gson
to serialise
or deserialise
Json data
.
现在什么是有问题的,问题从哪里开始以获得错误响应,我正在使用 ResultWrapper.kt
:
Now what is problematic and where problem started in to get error response I am using 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
,例如:
So, now I can call this enqueue fun
from anywhere in app
like:
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
时出现了编译错误
,因为在 ResultWrapper.ResponseWrapper接口中
中定义了一个方法,该方法使用onSuccess(response:Response< Any>)暂停乐趣..因此,这里发生了类型转换问题!
But I am getting compile error
for passing response
in resultWrapper.enqueue()
because in ResultWrapper.ResponseWrapper interface
there is method defined with suspend fun onSuccess(response: Response<Any>)
. So, type conversion problem occurred here!
如果翻新 CallBack< T>
可以处理任何类型的 Model或Data类
,并返回准确的类型.像上面的服务一样,需要 Model_Video_List
类作为响应,而其他服务则需要有自己的服务呢?是否只有办法为每项服务使用单独的功能?还是只能在Java中使用!!
If Retrofit CallBack<T>
can handle any type of Model or Data classes
and return which is exact tpyed. Like above service requires Model_Video_List
class in response and other services requires there own then what to do for it? Is there only way to use separate function for every service? Or is it only possible in Java?!
推荐答案
您可以在类 ResultWrapper
中引入通用参数类型 T
,因此无论何时创建实例对于此类,您必须指定实际类型代替 T
.
You can introduce a generic parameter type T
in your class ResultWrapper
, so whenever you create an instance of this class you must specify an actual type in place of 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)
}
}
}
}
}
并将您的方法更改为此:
And also change your method to this:
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) {
}
})
}
}
这篇关于为翻新Kotlin协程创建自定义网络列表器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!