java.lang.IllegalStateException: Realm access from incorrect thread.
Realm objects can only be accessed on the thread they were created.
这两天碰到一个bug,因为自己的不小心。bug如下:
提示出错的代码是这一段:
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
final RealmResults<Apple> realmResults = mRealm.where(Apple.class).findAll();
for(Apple apple:realmResults){
Log.d(TAG, "query "+apple.toString());
}
}
});
mRealm是Realm数据库实例,点击这里查看Realm官方文档,在这里我异步执行了一次查找,没有想到提示报错。
Realm objects can only be accessed on the thread they were created.
意思就是Realm对象只能在它创建的线程上访问。
首先说明一下,mRealm的创建代码如下:
mRealm = Realm.getInstance(new RealmConfiguration.Builder(this)
.name("test")
.build());
我在示例DEMO中的onCreate()方法中创建。然后点击界面上一个按钮时,再执行查找操作,我把查找代码放在事务当中,并且调用的是异步执行的接口,这是为了防止ANR,代码在文章最开始的地方。没有想到这里却抛出了一个异常,导致程序关闭。
那么怎么解决呢?
方法1 调用Transaction对象中的execute()中传递的参数对象
只需要把代码改成这样
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
//将之前的mRealm改成realm参数对象就可以了
final RealmResults<Apple> realmResults = realm.where(Apple.class).findAll();
for(Apple apple:realmResults){
Log.d(TAG, "query "+apple.toString());
}
}
});
问题解决。
方法2 设置Realm的DefaultInstance。
在Realm初始化的时代这样编写代码:
RealmConfiguration config = new RealmConfiguration.Builder(this)
.name("test")
.build();
Realm.setDefaultConfiguration(config);
mRealm = Realm.getDefaultInstance();
然后在异步调用的时候,获取它的DefaultInstance。
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
final RealmResults<Apple> realmResults =
Realm.getDefaultInstance().where(Apple.class).findAll();
for(Apple apple:realmResults){
Log.d(TAG, "query "+apple.toString());
}
}
});
用Realm.getDefaultInstance()
替换之前的mRealm
,同样不会再报错了。