Android Mosby MVI:不一致的意图绑定行为
我正在使用新库开发新的演示应用程序。 在演示者中定义意图时,如果在附加视图时触发/发出意图,则不一致 例如:让我们在活动中定义非常简单的意图Android Mosby MVI:不一致的意图绑定行为,android,mosby,Android,Mosby,我正在使用新库开发新的演示应用程序。 在演示者中定义意图时,如果在附加视图时触发/发出意图,则不一致 例如:让我们在活动中定义非常简单的意图 public Observable<Boolean> intentLoadData(){ return Observable.just(true); } 导航到新活动并返回时为否。重新附着视图时,意图将发出一个新项。在我的例子中,这将导致对后端的新APU调用以重新加载数据,而不是重用上一个ViewState。即使从未调用过reloadDa
public Observable<Boolean> intentLoadData(){
return Observable.just(true);
}
导航到新活动并返回时为否。重新附着视图时,意图将发出一个新项。在我的例子中,这将导致对后端的新APU调用以重新加载数据,而不是重用上一个ViewState。即使从未调用过reloadData()
,也会发生这种情况
这种行为感觉很不一致。在重新附着视图期间触发意图时,我如何能感觉到更好的控制
更新:
对我来说,更有趣的是,我如何避免重新连接时自动发出意图,而不完成可观察的。
随着PublishSubject的引入,活动将重新加载整个数据,即使只是旋转。Mosby MVI尊重反应流契约。查看
intentLoadData()
顺便说一句,您也可以使用Trello之类的库,它为生命周期事件提供可观察的流,但请记住,如果活动被破坏(即在屏幕方向更改期间),Navi会发出
onCompleted()
事件,因此您最终会遇到相同的情况:您必须确保onCompleted()如果您想稍后再次激发意图,则不会调用
。要回答我自己的问题并总结评论,以下是我的解决方案:
首先,我们必须了解Mosby3 MVI如何恢复视图,例如:旋转后,前后导航到不同的视图。
Mosby3保留演示者的实例。创建视图的新实例时,将恢复演示者并将其附着到视图onStart()
在新视图中,演示者将更新意图。因此,新视图将创建新的意图,演示者将使用PublishSubject
s订阅这些意图
如果先前视图的意图发出了onComplete()
则PublishSubject
也已完成,流将关闭。绑定到此目的的(交互者)逻辑将被取消订阅。因此,视图不能再触发此意图
在原始问题的例子中<代码>可观察。仅(true)关闭流。即使重新创建视图及其意图(旋转后),也不会发出新项。
mReloadDataSubject.startWith(true)
不会发出onComplete()
且流未关闭。当演示者重新订阅该意图时(轮换后),该意图发出startsWith(true)`。在本例中,这会导致每次旋转时完全重新加载数据
为了触发意图,有条件地重新加载是非常有帮助的
public Observable<Boolean> intentReloadData() {
//check if the data needs a reload in onResume()
return RxNavi.observe(this, Event.RESUME)
.filter(ignored -> mNeedsReload == true)
.map(ignored -> true);
}
公共可观察的intentReloadData(){
//在onResume()中检查数据是否需要重新加载
返回RxNavi.observe(此,事件恢复)
.filter(忽略->mNeedsReload==true)
.map(忽略->真);
}
我的问题更多的是相反的。使用PublishSubject有助于随后触发意图,但是在重新附加视图时,如何阻止它在bindIntents()
中发出?您说的“重新附加视图”是什么意思?你能给我一个具体的例子吗?我使用PublishSubject定义从web服务加载数据,就像我最初的问题一样。活动开始,数据将被加载。当我旋转设备时,在MviBasePresenter中的bindententactually()
期间再次触发加载意图。我想避免这种不必要的重新加载<在这种情况下,在attachView()
中调用code>bindententactually(),并将viewAttachedFirstTime
设置为false。这就是为什么我指的是重新连接。所以你只想发射一次?然后在发出一次意图后完成,例如可观察。just(true)
类似这样的内容:可观察。merge(initialloadingcontent,relloadingcontent)
,然后在发出一次意图后可以完成initialloadingcontent,即使用可观察。just(true)
。。。我会将可观察。合并(…)
到演示者中,让视图提供两种意图。我之所以要把它放到Presenter中,是因为视图会进行一些计算(合并),这会使视图的转储量减少一些。在Presenter中也有这个功能允许您使用一个简单的android单元测试来测试它,否则您将不得不编写一个android工具测试
private PublishSubject<Boolean> mReloadDataSubject = PublishSubject.create();
private void reloadData(){
mReloadDataSubject.onNext(true);
}
public Observable<Boolean> intentLoadData(){
return mReloadDataSubject.startWith(true);
}
public Observable<Boolean> intentLoadData(){
return Observable.just(true);
}
public class MyActivity extends MviActivity<MyView, MailListViewState> {
private PublishSubject<Boolean> mReloadDataSubject = PublishSubject.create();
public void onResume(){
super.onResume();
// Triggers on screen orientation changes and
// when navigating back to this screen from back stack
mReloadDataSubject.onNext(true);
}
public Observable<Boolean> intentLoadData(){
return mReloadDataSubject;
}
}
public Observable<Boolean> intentReloadData() {
//check if the data needs a reload in onResume()
return RxNavi.observe(this, Event.RESUME)
.filter(ignored -> mNeedsReload == true)
.map(ignored -> true);
}