Kotlin:如何从RxJava Subscriber继承

时间:2016-02-26 20:58:42

标签: android rx-java kotlin

我希望我的NewsListSubscriber继承自使用泛型类型的RxJava订阅者,但我得到了一个"类型不匹配"我调用UseCase执行方法时出错。我多次阅读Kotlin文档中的泛型页面,但我无法找到解决方案。

这是我的UseCase:

#ContentHolder
{
    float:left;
    padding-left: 10px;
    width: 590px;
    min-height: 500px;
}

#SideBar
{
    float: left;
    width: 200px;
    min-height: 500px;
    background-color: #4a4a4a;
    border-top: 2px solid #404040;
    border-top-left-radius: 7px;
    background-image: url('Images/SideBar.gif');
    background-repeat: repeat-x;
    background-position: bottom;
}

#Footer
{
    clear: both;
    background: #404040;
    font-size: 10px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    color: #707070;
    text-shadow: 0 1px 0 #202020;
}

以下是我的称呼方式:

abstract class UseCase(private val threadExecutor: IThreadExecutor,
                       private val postExecutionThread: IPostExecutionThread) {

    private var subscription = Subscriptions.empty()

    fun execute(UseCaseSubscriber: rx.Subscriber<Any>) {
        subscription = buildUseCaseObservable()
                .subscribeOn(Schedulers.from(threadExecutor))
                .observeOn(postExecutionThread.getScheduler())
                .subscribe(UseCaseSubscriber)
    }

    protected abstract fun buildUseCaseObservable(): Observable<out Any>

    fun unsubscribe() {
        if (!subscription.isUnsubscribed) {
            subscription.unsubscribe()
        }
    }
}

错误是

  

&#34;类型不匹配。必需:rx.Subscriber。发现:Presenters.NewsListPresenter.NewsListSubscriber&#34;

执行(NewsListSubscriber())&#34;线。我尝试过玩&#34; in&#34;和&#34; out&#34;关键字,但我仍然有同样的错误。

2 个答案:

答案 0 :(得分:2)

实际上有更好的方法来解决这个问题。我遇到了同样的问题,并且每个派生订阅者类中的类型转换都不是一个选项。

只需使用泛型类型参数更新抽象UseCase类。

abstract class UseCase<T>(private val threadExecutor: IThreadExecutor,
                   private val postExecutionThread: IPostExecutionThread) {

    private var subscription = Subscriptions.empty()

    fun execute(UseCaseSubscriber: rx.Subscriber<T>) {
        subscription = buildUseCaseObservable()
                .subscribeOn(Schedulers.from(threadExecutor))
                .observeOn(postExecutionThread.getScheduler())
                .subscribe(UseCaseSubscriber)
    }

    protected abstract fun buildUseCaseObservable(): Observable<T>

    fun unsubscribe() {
        if (!subscription.isUnsubscribed) {
            subscription.unsubscribe()
        }
    }
}

当您声明派生的UseCase类时,在调用超类时使用您的具体类型作为泛型参数。

class ConcreteUseCase(val threadExecutor: IThreadExecutor,
               val postExecutionThread: IPostExecutionThread)
               : UseCase<ConcreteType>(threadExecutor, postExecutionThread)

这样做,您可以在execute来电中使用已键入的订阅者。

getNewsListInteractor.execute(NewsListSubscriber())

...

private inner class NewsListSubscriber : rx.Subscriber<List<NewsModel() {
    override fun onCompleted() {// TODO}

    override fun onError(e: Throwable) {// TODO}

    override fun onNext(t: List<NewsModel>) {// TODO}
}

答案 1 :(得分:0)

我发现实际上这个解决方案很简单:我的NewsListSubscriber类必须从rx.Subscriber&lt; Any&gt;扩展而来。而不是rx.Subscriber&lt; MyWantedClass&gt;。这意味着我需要将收到的对象强制转换为想要的类型。

private inner class NewsListSubscriber : DefaultSubscriber<Any>() {

    override fun onCompleted() {}

    override fun onError(e: Throwable) {}

    override fun onNext(t: Any?) {
        val newsList = t as List<News>
        ...
    }
}

在Java中,演员阵容是在后台完成的,但在Kotlin中我们需要自己完成。

我还删除了UseCase类中的所有“in”或“out”关键字。