MickaelG MickaelG - 3 months ago 14
Android Question

Kotlin: How to inherit from RxJava Subscriber

I want my NewsListSubscriber to inherit from an RxJava Subscriber which use a generic type but I get a "Type mismatch" error when I call the UseCase execute method. I read many times the generics page from the Kotlin documentation but I can't find the solution.

Here is my UseCase:

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()
}
}
}


And here is how I call it:

override fun loadNewsList() {
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}
}


The error is


"Type mismatch. Required: rx.Subscriber. Found: Presenters.NewsListPresenter.NewsListSubscriber"


in the "execute(NewsListSubscriber())" line. I tried playing with the "in" and "out" keywords but I still have the same error.

Answer

I found the solution that is pretty simple actually: my NewsListSubscriber class has to extends from rx.Subscriber<Any> instead of rx.Subscriber<MyWantedClass>. It means I need to cast the received objects to the wanted type.

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>
        ...
    }
}

In Java the cast is done in background but in Kotlin we need to do it ourself.

I also removed all "in" or "out" keywords in my UseCase class.