Kotlin:如何从RxJava订阅者继承
我希望我的NewsListSubscriber继承自使用泛型类型的RxJava订阅服务器,但是当我调用UseCase execute方法时,出现“类型不匹配”错误。 我从Kotlin文档中多次阅读泛型页面,但找不到解决方案。
这是我的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() } } }
这就是我所说的:
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} }
错误是
“Type mismatch。Required:rx.Subscriber。Found:Presenters.NewsListPresenter.NewsListSubscriber”
在“执行(NewsListSubscriber())”行。 我试着玩“进”和“出”关键字,但我仍然有同样的错误。
实际上有更好的方法来解决这个问题。 我遇到了同样的问题,并在每个派生的订户类内部强制类型转换不是一个选项。
只需使用泛型类型参数更新抽象的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} }
我发现实际上很简单的解决方案:我的NewsListSubscriber类必须从rx.Subscriber <Any>而不是rx.Subscriber <MyWantedClass>进行扩展。 这意味着我需要将收到的对象转换为想要的类型。
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”关键字。