Я использую сервис ретрофита без обратного вызова. Таким образом, это, вероятно, происходит с Kotlin Coroutine suspend fun
. Я упомянул много блогов, средств массовой информации и так много учебников. Ну, это легко получить ответ, используя сопрограмму scope
с IO and Main
потоком.
Итак, после обращения к некоторым примерам я собираюсь сделать код, подобный этому:
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
class - это класс данных моего ответа.
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 data
.
Теперь, что является проблемой c и где возникла проблема, чтобы получить ответ об ошибке Я использую 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)
}
}
}
}
}
Итак, теперь я могу назвать это enqueue fun
из любого места в app
как:
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) {
}
})
}
}
Но я получаю compile error
для передачи response
в resultWrapper.enqueue()
, потому что в ResultWrapper.ResponseWrapper interface
есть метод, определенный с suspend fun onSuccess(response: Response<Any>)
. Таким образом, здесь возникла проблема с преобразованием типов!
Если Retrofit CallBack<T>
может обрабатывать любой тип Model or Data classes
и возвращать, который является точным tpyed. Как и в случае с вышеприведенным сервисом, в ответ требуется класс Model_Video_List
, а для других сервисов требуется собственный класс, что делать для этого? Есть ли единственный способ использовать отдельную функцию для каждого сервиса? Или это возможно только в Java?!