android - 导致大量 ANR 的 Realm

标签 android realm

在我自己的测试中,我没有遇到这个问题,但是一旦我的应用程序发布,ANR 就开始大量涌入。我的应用程序目前有 22 个 ANRs,其中一些被报告多达 100 次。所有痕迹似乎都来自于尝试在 UI 线程上创建一个新的 Realm 实例。

"main" prio=5 tid=1 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x4183ede0 self=0x417548b8
| sysTid=19680 nice=0 sched=0/0 cgrp=apps handle=1073975684
| state=S schedstat=( 2816413167 710323137 3658 ) utm=215 stm=66 core=1
at io.realm.Realm.createAndValidate(Realm.java:~495)
- waiting to lock <0x41df9c98> held by tid=12          (IntentService[UASyncService])
at io.realm.Realm.create(Realm.java:486)
at io.realm.Realm.getInstance(Realm.java:404)
at io.realm.Realm.getInstance(Realm.java:366)
at io.realm.Realm.getInstance(Realm.java:347)

我相信这个问题的根源是,正如 beeender 提到的,我在工作线程中有一个打开的 Realm 事务,这阻止了我在 UI 线程上获取 Realm 实例的尝试,导致 ANR。

待有解决方案后我会再更新

*编辑:添加更新信息。

最佳答案

Realm 不再有这个问题。

作为引用,我当时的解决方案是:

感谢 beeender 为我指明了正确的方向并链接了此 PR https://github.com/realm/realm-java/pull/1297

问题

当有挂起的 Realm 事务时,在不同线程上对 Realm.getInstance 的任何调用都将阻塞,直到挂起的事务被提交或取消。

在我的例子中,我有一个 IntentService,它用现有的用户数据填充我的 Realm,同时我尝试通过在 UI 线程上查询 Realm 来显示任何当前数据。虽然查询很简单,通常不会引起任何问题,但如果 IntentService 中有待处理的事务,调用 Realm.getInstance 将被阻塞,阻塞 UI 线程,可能导致 ANR。

我的第一个解决方案尝试是拉取 beeender 的 PR 分支并创建一个 jar。我相信这个修复确实让我更进一步,允许在不阻塞的情况下创建 Realm 实例,但是 UI 线程仍然被我试图在 UI 线程上执行的小事务阻塞。

解决方案

我实现的解决方案涉及几个步骤:

  • 为我的所有模型创建重复对象。副本不扩展 RealmObject(因为 RealmObjects 不能跨线程使用。)
  • 将对 Realm 的所有访问移至后台线程。基本上,我将查询包装在 AsyncTasks 中,并添加了返回模型的非 RealmObject 版本的监听器。
  • 多做小额交易,而不是少做大额交易。之前我在创建许多新 RealmObject 的循环的任一侧开始并提交事务,现在我开始并提交每个对象的事务。这样做的目的是减少 Realm 可能处于打开事务状态的总不间断时间,这样我为 UI 提供数据的查询就可以完成,而无需等待那么长时间。

结论

我最初对使用 Realm 犹豫不决,因为它仍处于测试阶段,而且 RealmObjects 不能跨线程使用。经过一些测试后,我确信我可以毫无问题地在 UI 线程上执行简单的查询(尽管我的直觉仍然有罪恶感。)

Overall Realm 是一个值得关注的好项目,但我觉得它还没有为大型商业项目做好准备。在这个项目上使用 Realm 可能节省了一些前期时间,但它却让许多客户不满意,而且问题难以诊断。

*编辑:澄清问题。

关于android - 导致大量 ANR 的 Realm ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31521421/

相关文章:

java - Android 异步任务中的返回列表

android - 当我在 android 中单击后退按钮时,计时器没有停止

android - 在 Android 应用程序中隐藏加密 key

java - Realm Java 迁移 : Property has been made required

android - Espresso 中错误线程的 Realm 访问

java - 使用从微调器中选择的项目填充 imageview

Android java 无法调用另一个类的函数。怎么做?

android - 即时应用程序和拆分 abi

Android Realm : Primary key constraint broken. 值已存在:0

ios - 加密 Realm 数据库并崩溃