我第一次尝试Kotlin Coroutines和Flow,并且尝试通过MVI-ish方法重现我在Android上使用RxJava的特定流程,但是我很难正确设置它,并且我基本上被卡住了此时。
RxJava应用程序本质上是这样的:
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有一个PublishSubject
类型的Event
实例。即MainActivityView.Event.OnViewInitialised
,MainActivityView.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
}
}
}
}
然后由Event
调用的MainActivityViewModel
类拾取这些.compose(viewModel())
,然后将接收到的Event
转换为新的{{ 1}}通过State
。视图模型返回一个新状态,其中带有ObservableTransformer<Event, State>
,然后可以通过renderEvent
函数在MainActivity
中对其进行操作。
render(state: MainActivityView.State)
我可以用协同程序/流/通道实现某种相同的流吗?甚至可能简化了吗?
类似的问题:
答案 0 :(得分:0)
您的pip install --user cherrypicker
可能看起来像这样。
MainActivity
答案 1 :(得分:0)
我认为您正在寻找的是compose
和ObservableTransformer
的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
函数。
它与我们在RxJava中使用的并不完全相同,但是应该可用于实现相同的结果。