有没有办法通过协同程序/流/通道在Kotlin中实现此rx流?

时间:2019-09-05 15:58:09

标签: android kotlin kotlin-coroutines

我第一次尝试Kotlin Coroutines和Flow,并且尝试通过MVI-ish方法重现我在Android上使用RxJava的特定流程,但是我很难正确设置它,并且我基本上被卡住了此时。

RxJava应用程序本质上是这样的:

MainActivityView.kt

object MainActivityView {

    sealed class Event {
        object OnViewInitialised : Event()
    }

    data class State(
        val renderEvent: RenderEvent = RenderEvent.None
    )

    sealed class RenderEvent {
        object None : RenderEvent()
        class DisplayText(val text: String) : RenderEvent()
    }
}

MainActivity.kt

MainActivity有一个PublishSubject类型的Event实例。即MainActivityView.Event.OnViewInitialisedMainActivityView.Event.OnError等。初始事件是通过受试者的onCreate()通话在.onNext(Event)中发送的。

@MainActivityScope
class MainActivity : AppCompatActivity(R.layout.activity_main) {

    @Inject
    lateinit var subscriptions: CompositeDisposable

    @Inject
    lateinit var viewModel: MainActivityViewModel

    @Inject
    lateinit var onViewInitialisedSubject: PublishSubject<MainActivityView.Event.OnViewInitialised>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupEvents()
    }

    override fun onDestroy() {
        super.onDestroy()
        subscriptions.clear()
    }

    private fun setupEvents() {
        if (subscriptions.size() == 0) {
            Observable.mergeArray(
                onViewInitialisedSubject
                    .toFlowable(BackpressureStrategy.BUFFER)
                    .toObservable()
            ).observeOn(
                Schedulers.io()
            ).compose(
                viewModel()
            ).observeOn(
                AndroidSchedulers.mainThread()
            ).subscribe(
                ::render
            ).addTo(
                subscriptions
            )

            onViewInitialisedSubject
                .onNext(
                    MainActivityView
                        .Event
                        .OnViewInitialised
                )
        }
    }

    private fun render(state: MainActivityView.State) {
        when (state.renderEvent) {
            MainActivityView.RenderEvent.None -> Unit
            is MainActivityView.RenderEvent.DisplayText -> {
                mainActivityTextField.text = state.renderEvent.text
            }
        }
    }

}

MainActivityViewModel.kt

然后由Event调用的MainActivityViewModel类拾取这些.compose(viewModel()),然后将接收到的Event转换为新的{{ 1}}通过State。视图模型返回一个新状态,其中带有ObservableTransformer<Event, State>,然后可以通过renderEvent函数在MainActivity中对其进行操作。

render(state: MainActivityView.State)

我可以用协同程序/流/通道实现某种相同的流吗?甚至可能简化了吗?

类似的问题:

3 个答案:

答案 0 :(得分:0)

您的pip install --user cherrypicker可能看起来像这样。

MainActivity

答案 1 :(得分:0)

我认为您正在寻找的是composeObservableTransformer的Flow版本,据我所知没有。您可以使用let运算符来做类似 的操作:

MainActivity:

yourFlow
  .let(viewModel::invoke)
  .onEach(::render)
  .launchIn(lifecycleScope) // or viewLifecycleOwner.lifecycleScope if you're in a fragment

ViewModel:

operator fun invoke(viewEventFlow: Flow<Event>): Flow<State> = viewEventFlow.flatMapLatest { event ->
  when (event) {
    Event.OnViewInitialised -> flowOf(onViewInitialisedEvent())
  }
}

就共享流程而言,我将关注以下问题:

Dominic的答案可能可以替代发布的主题,但我认为协程团队正在远离BroadcastChannel,并打算在不久的将来弃用它。

答案 2 :(得分:0)

kotlinx-coroutines-core提供了transform函数。

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/transform.html

它与我们在RxJava中使用的并不完全相同,但是应该可用于实现相同的结果。