在我自己的测试中,我没有遇到这个问题但是一旦我的应用程序发布,ANR开始涌入。我的应用程序目前有22个ANR,其中一些被报告为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的尝试。
我有解决方案后会再次更新。
*编辑:添加了更新信息。
答案 0 :(得分:3)
领域不再有这个问题。
作为参考我当时的解决方案是:
感谢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线程上执行的小事务阻止。
<强>解决方案强>
我实施的解决方案涉及几个步骤:
<强>结论强>
我最初对使用Realm犹豫不决,因为它仍然处于测试阶段以及不能跨线程使用RealmObjects的警告。经过一些测试后,我确信我可以毫无问题地在UI线程上执行简单查询(尽管我的内心仍然有一种内疚感。)
整体领域是一个值得关注的伟大项目,但我觉得它还没有为大型商业项目做好准备。在这个项目中使用Realm可能已经节省了一些时间,但它使许多不满的客户和难以诊断的问题付出了代价。
*编辑:澄清问题。
答案 1 :(得分:0)
Realm's introduction example显示他们使用AsyncTask进行读写操作。
任何代价高昂的I / O,无论是来自网络,数据库还是大型文件,都应该远离主线程,因为它会导致UI缓慢。在没有看到你的代码的情况下,我猜想如果你得到一个ANR,你可能会为主线程做一些过于复杂的事情。