RxJava - 订阅的扩展函数

时间:2018-03-20 01:49:06

标签: android kotlin rx-java kotlin-extension

我试图使用RxJava / Retrofit,我想编写一个扩展函数来用网络结果包装一些逻辑。

我有一个NetworkConsumer课,Consumer

abstract class NetworkConsumer<T> : Consumer<NetworkResponse<T>> {

    override fun accept(response: NetworkResponse<T>) {
        if (response.isSuccessful()) {
            onSuccess(response.data)
        } else {
            onFailure()
        }
    }

    // other functions such as onSuccess and onFailure
}

我想创建一个扩展函数,以允许我像使用普通Consumers一样使用Lambda语法。

service.login(email, password)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({
            result -> 
                // result is the correct object
        }, {
           // handle the error
        }) 

但是,如果我想使用我的NetworkConsumer,我必须这样做:

.subscribe(object : NetworkConsumer<LoginResponse>() {
                    override fun onSuccess(response: LoginResponse) {
                        // ...

所以我试着写一个扩展函数,比如:

fun <T> Observable<T>.subscribe(onNext: NetworkConsumer<in T>, onError: Consumer<in Throwable>): Disposable {
    return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer<Any>())
}

但它没有编译,错误是:

> Type mismatch. 

> Required: Consumer<in T!>! 

> Found: NetworkConsumer<in T>

1 个答案:

答案 0 :(得分:0)

猜猜是因为您的NetworkConsumer类扩展了NetworkResponse<T>泛型类型。

您的扩展功能与Observable<T>对象一起使用,该对象需要Consumer<T>个对象进行订阅。当您将NetworkConsumer订阅时,它等于Consumer<NetworkResponse<T>>对象。

所以这里不匹配:Consumer<T>针对Consumer<NetworkResponse<T>>。您应该像NetworkConsumer<T> : Consumer<T>一样重写您的课程。

<强>加

如果仅为消费者使用NetworkResponse类型很重要,您可以执行以下操作:

1)为NetworkConsumer类添加泛型类型的扩展语句。

abstract class NetworkConsumer<T : NetworkResponse<TResponce>, TResponce> : Consumer<T> {...

此处T - 在父Consumer类中输入“put”,只能NetworkResponse。和TResponce - 应该放在NetworkResponse中的真实回复类型。

2)将所有retrofit api接口方法作为返回NetworkResponse<...>对象。在此之后不应该有任何编译错误,但这还不够 - retrofit不知道如何创建NetworkResponse类的对象。

3)我认为这一刻最困难。您需要创建your own converter factory来说明retrofit如何为您创建响应对象。可以this question可以提供帮助,也可以在谷歌找到类似的解决方案。