Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Mosby MVI:不一致的意图绑定行为_Android_Mosby - Fatal编程技术网

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);
}