领域长期存在的背景实例



我已经阅读了有关在后台非 Looper 线程上保留长期Realm实例的警告。我还看到有人建议快速打开和关闭Realm实例不是最好的主意。鉴于这些约束(如果任何一个无效,请告诉我),我正在尝试确定将 Realm 与 websocket 一起使用的最佳方式,其中 websocket 事件包含需要访问Realm的信息。

特别是,在这些选项(或完全其他选项)之间切换的正确方法是什么?

  • 打开和关闭每个事件的Realm
  • 在线程开始时打开Realm,定期(每 30 秒左右)在线程上开始并提交事务以使 Realm 数据库保持最新状态。
  • 为处理 websocket 消息的线程分配Looper。在线程上创建一次Realm实例,并在线程的生存期内使其保持打开状态,使用Looper使其保持最新状态。

其他值得注意的事情:

  • 客户端已在 UI 线程上打开Realm。因此,据我了解,这意味着后台线程至少不需要支付架构验证的代价。
  • 无法预测 websocket 事件的频率。在典型情况下,每秒的事件可能不超过一两个。但是,如果服务器上发生了更改一堆对象的大型操作,则客户端可能会相当快地收到数百或数千个 websocket 事件。

在每个事件上打开和关闭 Realm

就个人而言,根据那些说"他们的 Realm 已经过时"的人,我发现这是可靠的,所以这只有在你实际调用 refresh() 后才有意义Realm.getDefaultInstance().

在线程开始时打开 Realm,定期(每 30 秒左右)在线程上开始并提交事务,以使 Realm 数据库保持最新状态。

定期更新会导致不必要的事务,或者时不时地"不知道变化"。

另外,您实际上不需要提交事务来强制更新,因为beginTransaction()已经将 Realm 数据库带到了新版本。

realm.beginTransaction();
realm.cancelTransaction();

这本身就足够了 - 但从技术上讲,这是一种解决方法,用于替换使用refresh()(不是公共 API 的一部分),如果事务在另一个线程上打开,则还会阻塞线程。

为处理 websocket 消息的线程分配一个 Looper。在线程上创建一次 Realm 实例,并在线程的生命周期内保持打开状态,使用 Looper 使其保持最新状态。

如果您想始终确保当前线程始终可靠地保持最新状态,并且不会阻塞进程中的其他线程,那么这就是要走的路。


所以两种方式是:

1.) 保留一个只在事务中对 Realm 数据库进行查询的newSingleThreadedExecutor()

2.) 根据需要保持HandlerThread活动状态,并在那里执行 Web 套接字 + 查询内容

(就我个人而言,我只在 RxJava +AndroidSchedulers.from(handlerThread.getLooper())中使用过HandlerThread)。

最新更新