为翻新Kotlin协程创建自定义网络列表器 [英] Creating custom network listner for Retrofit Kotlin Coroutine

查看:55
本文介绍了为翻新Kotlin协程创建自定义网络列表器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用改装服务,而没有使用回调.因此,它可能与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协程创建自定义网络列表器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆