响应式 协程_为协程创建改造calladapter以将响应作为状态进行处理

响应式 协程

In the past, we used to use JakeWharton/retrofit2-kotlin-coroutines-adapter in order to use Retrofit with Coroutines.

过去,我们曾经使用JakeWharton / retrofit2-kotlin-coroutines-adapter来将Retrofit与Coroutines一起使用。

But since Retrofit supports the suspend modifier on functions for Kotlin now, we don’t have to do this anymore.See Retrofit version 2.6.0 (2019–06–05)

但是由于Retrofit现在支持Kotlin函数上的suspend修饰符,因此我们不再需要这样做。请参见Retrofit版本2.6.0(2019–06–05)

So now using Retrofit with Coroutines is as simple as this

因此,现在将Coroutines与Retrofit一起使用就这么简单

@GET("users/{id}")
suspend fun user(@Path("id") id: Long): User

Enough talking about using Retrofit and Coroutines because there are tons of articles about this and let’s talk about error handling.

足够讨论使用Retrofit和Coroutines的问题,因为有很多关于此的文章,让我们谈谈错误处理。

In this article I will show how can we create our own Retrofit CallAdapter to handle the API calls errors and success states.

在本文中,我将展示如何创建自己的Retrofit CallAdapter来处理API调用错误和成功状态。

By the end of the article you should be able to do the following:

在本文末尾,您应该可以执行以下操作:

Sample
样品

创建网络响应密封类 (Create Network Response Sealed Class)

First, let’s model our responses states by creating a sealed class that represents the API call response states.

首先,让我们通过创建一个表示API调用响应状态的密封类来对响应状态进行建模。

Most probably we need 4 states:

我们很可能需要4个状态:

  1. Success which is a data class that should contain the body of the success state of the request.

    Success是数据类,应包含请求成功状态的主体。

  2. ApiError which represents the non-2xx responses, it also contains the error body and the response status code.

    ApiError代表非2xx响应,它还包含错误正文和响应状态代码。

  3. NetworkError which represents network failure such as no internet connection cases.

    NetworkError表示网络故障,例如没有Internet连接情况。

  4. UnknownError which represents unexpected exceptions occurred creating the request or processing the response, for example parsing issues.

    代表发生意外异常的UnknownError发生在创建请求或处理响应(例如解析问题)时。

创建我们自己的呼叫转换器 (Create our own Call transformer)

In order to make Retrofit return NetworkResponse when topic() API call is triggered, we need to write a custom CallAdapter

为了在触发topic() API调用时使Retrofit返回NetworkResponse ,我们需要编写一个自定义的CallAdapter

First step to create our own CallAdapter is implementing Call interface from Retrofit

创建我们自己的CallAdapter是从Retrofit实现Call接口

The method that has most of the logic in our implementation of the Call interface is enqueue.

enqueue是我们实现Call接口时具有大多数逻辑的方法。

What is the enqueue method?

enqueue方法是什么?

Asynchronously send the request and notify callback of its response or if an error occurred talking to the server, creating the request, or processing the response.

异步发送请求,并将响应通知给回调,或者如果在与服务器交谈,创建请求或处理响应时发生错误,则将其通知。

So we will implement enqueue method and check the response, then return the correct callback.

因此,我们将实现enqueue方法并检查响应,然后返回正确的回调。

enqueue takes a callback which has two methods to implement:

enqueue采用回调,该回调具有两种实现方法:

  1. onResponse: which is invoked for a received HTTP response, this response could be success response or failure one.

    onResponse :为收到的HTTP响应调用,此响应可以是成功响应,也可以是失败响应。

    So we have to check here if the response is successful, we return the success state of our

    因此,我们必须在此处检查响应是否成功,然后返回我们的成功状态

    NetworkResponse sealed class

    NetworkResponse密封类

    If it’s not a success response, we try to parse the error body as the expected error data class we provide as a type, if the parse succeeded we return the error as

    如果不是成功响应,则尝试将错误正文解析为我们作为类型提供的预期错误数据类,如果解析成功,则将错误返回为

    ApiError state, otherwise it’s UnknownError.

    ApiError状态,否则为UnknownError

  2. onFailure: which is invoked when a network exception occurred talking to the server or when an unexpected exception occurred creating the request or processing the response.

    onFailure :当发生网络异常与服务器通信或发生意外异常以创建请求或处理响应时调用。

    Here we can simply check if the exception is

    在这里,我们可以简单地检查异常是否为

    IOException then we return the NetworkError state, otherwise it should be UnknownError state.

    IOException那么我们返回NetworkError状态,否则就应该是UnknownError状态。

enqueue method enqueue method

The rest of the methods of Call interface are simple, we will just delegate them to the original call.

Call接口的其余方法很简单,我们只将它们委托给原始调用。

So the our Call implementation should look like this

因此,我们的Call实现应如下所示

NetworkResponseCall
NetworkResponseCall

创建自己的CallAdapter (Create your own CallAdapter)

Now it’s time to create our CallAdapter

现在是时候创建我们的CallAdapter

Creating CallAdapter is very straight forward, we will need to implement only two methods

创建CallAdapter非常简单,我们只需要实现两种方法

responseType Returns the value type that this adapter uses when converting the HTTP response body to a Java object

responseType返回此适配器将HTTP响应主体转换为Java对象时使用的值类型。

adapt Returns an instance of T which delegates to call, here we will use our NetworkResponseCall that we just created.

adapt返回T的一个实例,委托该实例进行调用这里我们将使用刚刚创建的NetworkResponseCall

创建自己的CallAdapter Factory (Create your own CallAdapter Factory)

Next step is creating our CallAdapter.Factory

下一步是创建我们的CallAdapter.Factory

CallAdapter.Factory has only one abstract method that we should implement which is get.

CallAdapter.Factory只有我们应该实现的一种抽象方法get

get method in the CallAdapter.Factory should return a callback adapter for interface methods that it could handle or null if it’s can’t be handled by this factory.

CallAdapter.Factory中的get方法应该为它可以处理的接口方法返回一个回调适配器,如果该工厂无法处理,则返回null。

So simply our get method in our custom CallAdapter.Factory should check if the returnType is our sealed class for the API response calls, and then handle it.If the caller isn’t asking for our Sealed Class, return null, this isn’t the right adapter.

所以简单地在自定义CallAdapter.Factory get方法应该检查returnType是否是API响应调用的密封类,然后对其进行处理。如果调用方不要求我们的密封类,则返回null,这不是正确的适配器。

What does this mean?

这是什么意思?

But there is something we need to know first about how suspend functions work with Retrofit.

但是,我们首先需要了解有关suspend功能如何与Retrofit一起工作的一些知识。

@GET("users/{id}")
suspend fun user(@Path("id") id: Long): User

Behind the scenes this behaves as if defined as fun user(...): Call<User> and then invoked with Call.enqueue

在幕后,它的行为就像定义为fun user(...): Call<User> ,然后用Call.enqueue调用

So this means when we have a suspend function like this

所以这意味着当我们有这样的暂停功能时

suspend fun user(): ApiResponse<User, Error>

It’s actually

其实是

fun user(): Call<ApiResponse<User, Error>>

So after removing the Call type we have to make sure that the inner type is ApiResponse

因此,在删除Call类型之后,我们必须确保内部类型为ApiResponse

Now we reached a point, where we have the response as ApiResponse<Success, Error>

现在,我们到达了一个响应点,即ApiResponse<Success, Error>

Next, we need extract the success and error types from the ApiResponse parameterized type.

接下来,我们需要从ApiResponse参数化类型中提取成功和错误类型。

The base CallAdapter.Factory in Retrofit has a function named getParameterUpperBound which should help us getting the success/error types from the parameterized type ApiResponse

CallAdapter.Factory中的基本CallAdapter.Factory有一个名为getParameterUpperBound的函数,该函数应该帮助我们从参数化类型ApiResponse获取成功/错误类型。

Then get the error converter and return

然后获取错误转换器并返回

NetworkResponseAdapterFactory
NetworkResponseAdapterFactory

使改造知道您的呼叫适配器 (Make retrofit aware of your Call Adapter)

Finally you need to add our custom CallAdapterFactory to Retrofit while initializing it

最后,您需要在初始化时将我们的自定义CallAdapterFactory添加到Retrofit

专家提示: (Protip:)

If you happen to have a generic error model that your API uses for most/all of the endpoints you can save yourself sometimes and code by creating a typealias that wraps this generic error model and the success type like this

如果您碰巧有一个API用于大多数/所有端点的通用错误模型,则有时可以保存自己并编写代码,方法是创建一个包装该通用错误模型和成功类型的类型typealias

typealias GenericResponse<S> = NetworkResponse<S, GenericApiError>

示例项目: (Sample Project:)

I created a sample App, you can check it out on GitHub

我创建了一个示例应用程序,您可以在GitHub上进行检查

Feedback is always welcome :)

随时欢迎反馈:)

GitHub | LinkedIn | Twitter

GitHub | LinkedIn | 推特

翻译自: https://proandroiddev.com/create-retrofit-calladapter-for-coroutines-to-handle-response-as-states-c102440de37a

响应式 协程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值