目的:在用户使用前,就能快速看到最新数据,并且还不影响UI线程,采用异步事务操作。
在应用启动时,初始化化Realm后,获取数据库数据,异步线程中进行事务操作, 如下几个坑点(只有刚初始化才会出现,后面就正常了)
1.deleteAllFromRealm
原代码:
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<MSG> toDeletedResults = realm.where(MSG.class)
.findAll();
//删除消息
if (toDeletedResults.size() > 0)
toDeletedResults.deleteAllFromRealm();
});
报错:Must be in a write transaction in /Users/cm/Realm/realm-java-release/realm/realm-library/src/main/cpp/io
比较坑,明明在事务里,还报错需要开启事务!!
改了很多种方式去实现,同步之类的,后面发现,是Application启动时,数据库需要一定的时间才能进行事务操作,注意:读数据是没问题的,好坑!!!
2.更新数据
原代码:
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Detail sessionMore = realm.where(Detail.class).equalTo("sid", session.getSid()).findFirst();
if (sessionMore == null)
sessionMore = realm.createObject(Detail.class, session.getSid());
if (info != null) {
sessionMore.setName("cc");
sessionMore.setAvatar("ccc");
}
}
});
报错: Can’t commit a non-existing write transaction
说明这个异步事务没有开启成功,表示很无语,在Application中启动的。。。
而且更坑的,这些问题导致崩溃了,会导致其他异步查询的报错:Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java-release/rea
我试了下,和方式没关系,就是Application一开始启动时,可能是需要一段时间,才能操作数据库。
3.解决方案
经过试验,失败了后等待一下,重试1次就好了,如果不是一定要成功的,可以手动加入限制重试次数逻辑,这里就不写出来了,比较简单(更新操作也一样)
private void delete() {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<MSG> toDeletedResults = realm.where(MSG.class)
.findAll();
//删除消息
if (toDeletedResults.size() > 0)
toDeletedResults.deleteAllFromRealm();
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {//失败了重试
handler.postDelayed(new Runnable() {
@Override
public void run() {
delete();
}
}, 1000);
}
});
}
个人感觉有坑就算了,Realm文档没写,很无语啊。
之前还碰到过,Realm进行批量更新几千条数据,报错,一个个更改没点事,额,个人感觉这数据库这趋势应该很快会被淘汰。。。