3

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

  1. 每个Activity都有自己的PresenterView(与 Activity 通信的接口)、ViewState(保存持久数据的可打包对象)。
  2. Activity销毁时:

    • 分离视图
    • 将 ViewState 保存在包中
    • 取消 Presenter 中的所有后台任务(完成后更新视图的任务)
    • 销毁演示者
  3. 重新创建Activity时:

    • 附加视图
    • 恢复 ViewState
    • 创建 Presenter 的新实例
    • 重启已取消的后台任务

除了最后一个问题- “重新启动已取消的后台任务”之外,我几乎完成了所有工作。用一个例子来讨论它会更容易。因此,假设我在演示者中有两种方法(Retrofit 2 调用):

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

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

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

你怎么看待这件事?如何改进?还有其他想法吗?

4

2 回答 2

1

我不知道您的 UI 是什么样子,但对我来说,您应该将一个大视图拆分为两个子视图:

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

从我的角度来看,MVP 始终只有一个模型显示在视图中(而不是像您的场景中那样两个),这始终是一个好主意。通常,如果您必须在同一个视图中处理两个模型,则表明您可以将此视图和演示者拆分为两个不同的。

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

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

然后你结合你的两个改造调用来创建一个DownloadModel,当两个调用都完成后你可以DownloadModel在你的视图中显示。使用改造和 rxjava,这非常简单(参见combineLatest()操作符)。在这种情况下,您就没有这个问题,因为您Presenter只有一种download()方法可以同时下载两者。如果一个明显快于另一个,那么很可能在方向更改和演示者重新创建之后,更快的一个来自改造缓存,因此这不应该让您感到太多困扰。

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

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

顺便提一句。为什么要重新发明轮子?听起来 Mosby 已经提供了您正在寻找的东西。Mosby 还支持保留在屏幕方向更改后幸存的演示者。

于 2015-11-20T19:42:16.473 回答
0

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

于 2016-10-31T14:38:00.267 回答