将用户操作发送到backstack中的活动

use*_*280 17 android

我正在开发社交应用.我们假设我有一堆活动A -> B -> C -> D.D在前台,用户按下"喜欢"按钮到那里(帖子,评论,用户等).为了刷新他们的数据,通知所有其他有关此操作的活动的最佳方法是什么?我在这里看到3个选项:

  1. 使用本地数据库和一些加载器自动刷新数据.然而,这需要大量的代码,如果我们有不同的数据模型与共享数据(例如BasicUserInfo,UserInfo,DetailedUserInfo).
  2. 将EventBus与粘性事件一起使用(Otto的生产者).在这种情况下,我必须只通知backstack活动并忽略那些将要创建的活动.此外,我必须管理事件覆盖.
  3. 使用WeakReferences的简单观察者模式来进行反向堆栈活动.但后来我遇到了将要重新实例化的被杀活动的问题.

真实的例子:

在Instagram:我打开一些特定用户的个人资料(A),在那里我打开一些特定的帖子(B),再打开个人资料(A)等等 - > B - > A - > B - > A ....所以它每次从Web加载数据.在步骤"n + 1"上出现对该帖子的新评论.如果我开始通过我的backstack回来,我将看到Instagram已经向所有B活动发送了这个"新"评论,而没有从web重新加载任何数据.所以我很有意思他们是怎么做到的.

bwt*_*bwt 5

通知系统(事件,观察者,BroadcastReceiver...)的主要用例是当您希望收件人在发生某些事情时或多或少立即采取行动时.

我认为这不是这种情况:后台活动不需要立即采取行动,因为它们不可见.此外,他们甚至可能不再存在(杀死/冻结).他们实际需要的是在他们回到前台时(可能在重新创建之后)获取最新数据.

为什么不简单地触发刷新onStart()onResume()(使用Loader或已经使用过的任何东西)?
如果"喜欢"的状态需要保留,你可以做它DonPause().如果没有,喜欢的对象可以存储在一个全局变量中(这实际上是一个粘性事件)


S.D*_*.D. 1

为了刷新他们的数据?

答案就在这里。活动不应该拥有数据。活动呈现数据并允许用户对其采取行动。数据本身应该位于可以通过活动实例(模型)进行交互的单独实体中。

此外,不应该假设后台堆栈中始终存在活动实例。当用户导航回来时,这些活动可以被销毁,然后由系统重新创建为不同的对象。创建整个活动时,数据始终会刷新。

将数据处理分离到专门的类中,活动可以轻松访问这些类,并且可以按需提供与活动的数据/事件绑定。界限Service是一个很好的候选者。

至于不从网络加载数据,您可以设置最近访问的数据的本地缓存(缓存,因为移动设备有严格的存储限制,服务器和数据库则不然)。因此,来自用户端的任何更改也会提交到此缓存并传播到服务器。所有这些最好由专门的数据类封装,而不是依赖于活动类中的返回堆栈或特殊代码。

作为一个模式,你可以构建Model为所涉及的数据实体构造类。编写一个 Web API 接口实现来与服务器通信。然后,在API接口之前放置一个缓存层。缓存将保留 API 层的传出更改和传入更新,并在不需要服务器调用时简单地反映数据请求。

缓存主要要做三件事:

  1. 驱逐:当新数据到来时,删除最不重要的数据,因此缓存保持固定大小。大多数缓存实现(就像这个)会自动执行此操作。
  2. 无效:有时,由于用户操作或服务器端的外部事件,某些数据必须刷新。
  3. 过期:数据可以设置一个时间限制,并且会被自动驱逐。这在强制定期刷新数据时非常有用。

现在大多数缓存实现都处理原始字节。我建议使用诸如Realm之类的对象数据库,并将其包装在类似缓存的功能中。因此,请求用户推文的典型流程是:

  1. 显示活动。
  2. Activity 绑定到数据服务,并表达其对“推文”的兴趣。
  3. 数据服务在Tweets缓存数据库表中查找上次获取的推文列表,并立即返回该列表。
  4. 但是,数据服务还会调用服务器在数据库本地拥有的最新推文的时间戳之后提供推文。
  5. 服务器返回最新的推文集。
  6. 数据服务使用新的传入数据更新对推文表示兴趣的所有绑定活动。此数据也会在本地缓存数据库中复制。此时,tweets 表也通过删除旧记录进行了优化。
  7. 当活动消失、停止、销毁等时,活动与数据服务解除绑定。
  8. 如果没有绑定活动对“推文”感兴趣,数据服务将停止加载更多推文。

通过维护与服务器的套接字连接并实时接收有趣的更改,您的数据实现可以更进一步。也就是说,只要有新数据传入,服务器就会调用上面的步骤 5。

太长了;将数据管理与活动分开,然后您可以独立于 UI 问题来发展它。