UI 元素在观察订阅之前检查其状态

UI element checks its state before observes subscribes

我在 Android 应用程序中更新刷新按钮状态时遇到问题。在我的交互器中,我有一对主题来控制刷新按钮的状态。

class PageInteractor {
    private var isRefreshActionEnabled = false
    private val refreshStatePublisher by lazy {
        BehaviorSubject.create<Boolean>().apply {
            onNext(false)
        }
    }
    private var refreshActionPublisher: PublishSubject<Unit>? = null

    fun observeRefreshButtonState(): Observable<Boolean> {
        return refreshStatePublisher
    }

    fun observeRefreshAction(): Observable<Unit> {
        if (refreshActionPublisher?.hasComplete() == false && refreshActionPublisher?.hasObservers() == true) {
            refreshActionPublisher?.onComplete()
        }

        return PublishSubject.create<Unit>()
            .also {
                refreshActionPublisher = it
                updateRefreshButtonState()
            }
            .doOnDispose {
                updateRefreshButtonState()
            }
    }

    fun setRefreshActionEnabled(value: Boolean) {
        if (isRefreshActionEnabled != value) {
            isRefreshActionEnabled = value
            updateRefreshButtonState()
        }
    }

    fun onRefreshAction() {
        refreshActionPublisher?.onNext(Unit)
    }

    private fun updateRefreshButtonState() {
        refreshStatePublisher.onNext(refreshActionPublisher?.hasComplete() == false
            && refreshActionPublisher?.hasObservers() == true)
    }
}

我在演示器中使用了这个交互器,它是一个 Moxy 演示器。

class PagePresenter(
        private val pageInteractor: PageInteractor
) : MvpPresenter<PageView> {
    override fun onFirstViewAttach() {
        super.onFirstViewAttach()

        pageInteractor
            .observeRefreshButtonState()
            .subscribe { isEnabled ->
                viewState.setRefreshButtonEnabled(isEnabled)
            }
            .addTo(disposable)
    }

    fun onRefreshButtonClicked() {
        pageInteractor.onRefreshAction()
    }
}

我的问题是当我打开页面时刷新按钮被禁用。我做了一些调试,似乎问题的根源在方法 observeRefreshAction 中。此方法在设置 refreshActionPublisher 时创建 PublishSubject,然后立即调用方法 updateRefreshButtonState。此方法通过调用 hasObservers 检查 PublishSubject 是否有任何订阅者,结果几乎总是错误的。发生这种情况是因为 PublishSubject 尚未返回给演示者,我可以在那里订阅它。

有什么方法可以解决这个问题吗?我曾尝试将 updateRefreshButtonState 移动到 doOnSubscribe,但没有帮助。

我试图理解问题并编写了一些代码并添加了一些注释。 因此,您不需要额外的 Publish Subject 来调用操作,您只需调用 onRefreshAction() 并更改 refreshButtonState 的当前状态即可。

import io.reactivex.Observable
import io.reactivex.subjects.BehaviorSubject
import kotlin.random.Random

class PageInteractor {

    // Initial value is false and after subscription, subscriber will receive that value
    private val refreshButtonState = BehaviorSubject.createDefault(false)

    fun observeRefreshButtonState(): Observable<Boolean> = refreshButtonState.distinctUntilChanged()

    // Invoke refresh action
    fun onRefreshAction() {
        // Change state or toggle state or something else
        // Currently generate random next state
        val nextAction = Random.nextBoolean()
        refreshButtonState.onNext(nextAction)
    }
}