Android MVP - 屏幕方向 - 保留演示者状态

时间:2015-11-20 16:45:29

标签: android retrofit mvp mosby

我对Android中的MVP模式有疑问。我想编写自己的“应用程序核心”,它将为演示者,视图等提供基类。它必须简单,干净且“稳定”。我的想法与莫斯比提供的内容非常类似,我正在努力实现这样的目标:

  1. 每个活动都有自己的演示者查看(界面) 与Activity交流), ViewState (parcelable object that 持有持久数据)。
  2. 活动销毁时

    • 分离查看
    • 将ViewState保存在包
    • 取消Presenter中的所有后台任务(完成时更新View的任务)
    • 摧毁Presenter
  3. 重新创建活动

    • 附上查看
    • 恢复ViewState
    • 创建Presenter的新实例
    • 重新启动已取消的后台任务
  4. 除了最后一期 - “重新启动已取消的后台任务”之外,我几乎完成了任务。用一个例子来讨论它会更容易。所以,假设我在演示者中有两种方法(Retrofit 2调用):

    • downloadUsers() - 从网络服务器和onSuccess更新视图中提取用户数据
    • downloadProject() - 从网络服务器和onSuccess更新视图中获取项目信息

    现在,当其中一个调用已启动但尚未完成时,用户正在更改配置。 如何在重新创建Presenter时知道应该重新启动哪一个?

    我想到的唯一想法是为每个任务创建一个持久的布尔标志,在任务启动时将其设置为 true ,并在完成时将其设置为 false 。当创建Presenter时,我将检查每个标志并重新启动相应的呼叫。

    您如何看待它?如何改进?还有其他想法吗?

2 个答案:

答案 0 :(得分:1)

我不知道你的用户界面是怎么样的,但对我而言,你应该把你的一个大视图分成两个子视图:

  • DownloadUsersView + ViewState由DownloadUsersPresenter
  • 管理
  • DownloadProjectsView + ViewState由DownloadProjectsPresenter
  • 管理

从我的观点来看,MVP只有一个单独的模型可以在View中显示(而不是像你的场景中那样)。通常,如果您必须在同一视图中处理两个模型,则表明您可以将此视图和演示者拆分为两个不同的模型。

或者,您可以将两个模型合并为一个模型,说

class DownloadModel {
  List<User> users;
  List<Project> projects;
}

然后您将两个Retrofit调用结合起来创建DownloadModel,当两个调用完成后,您可以在视图中显示DownloadModel。使用retrofit和rxjava这很简单(参见combineLatest()运算符)。在这种情况下,您不会遇到此问题,因为您的Presenter只有一个download()方法可以并行下载。如果一个比另一个快得多,那么很可能在定向改变和演示者重新创建之后,更快的一个来自改造缓存,所以这不应该让你感到烦恼。

正如您已经说过的那样,您也可以开始跟踪之前正在执行http调用的演示者,并在演示者重新实例化后重新调用它们,但这意味着演示者必须保存它的内部状态以及捆绑。莫斯比没有对此作出任何说明,并假设一般没有这种需要。因此,Mosby的默认Presenter实现不提供presenter.saveInstanceState(Bundle)presenter.restoreInstanceState(Bundle)。但这并不意味着你不能/不应该这样做。你可以在Mosby和你的实现中做到这一点。但是,如果您开始这样做,那么您只需将之前(不带mvp)的意大利面条代码放在Activity类中进入演示者。

因此,我再次强烈建议在MVP中为每个视图设置一个模型。

顺便说一下。为什么重新发明轮子?听起来像莫斯比已经提供了你正在寻找的东西。 Mosby还支持保留演示者,这些演示者可以在屏幕方向上发生变化。

答案 1 :(得分:0)

有许多方法和解决方案。我喜欢的是使用Loaders api。这是一个简单的库,您可以使用它来保持演示者实例的方向更改https://github.com/samiuelson/Preservely