ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Android Realm数据库使用总结及采坑记录

2019-08-31 12:43:23  阅读:656  来源: 互联网

标签:realm 采坑 plugin Object RealmObject 线程 Realm Android


文章目录

Realm使用注意事项

  • Realm默认运行在主线程,使用时须开启异步任务
  • Realm本身是单例类,可以多线程并发调用,但是RealmObject则不允许并发,每个RealmObject都绑定了一个TreadId,必须在创建该RealmObject的线程中使用它.
  • 在子线程查询出的数据无法在主线程使用,自己的方案是:子线程查询,置换为自己的Bean类,然后在主线程使用
  • 没有主键的realmObject无法进行update操作.所以如果要使用realm.copyToRealmOrUpdate(realmObject),那么这个realmObject必须设置primaryKey
  • 如果Realm关闭,所有查询得到的RealmObject都不能使用了,解决方案是复制一份数据到内存中。
  • 操作数据库必须在transaction中完成

常见问题

Object not managed by Realm, so it cannot be removed

Realm不支持直接通过deleteFromRealm删除Bean类,即使该Bean extends RealmObject,否则会报此异常

正确姿势:

根据指定字段,从数据库中查询到该Bean,然后再删除

/**
 * 从数据库中删除CollectBean
 * @param conType
 * @param relateId
 */
public void deleteCollectBeanByTypeAndId(String conType,int relateId){
    Realm realm = RealmUtils.getInstance().mRealm;
    CollectBean bean = realm.where(CollectBean.class)
            .equalTo(CollectBean.CON_TYPE, conType)
            .equalTo(CollectBean.RELATE_ID,relateId)
            .findFirst();
    realm.beginTransaction();
    bean.deleteFromRealm();
    realm.commitTransaction();
}

Realm accessed from incorrect thread

RealmObject自带线程保护功能,只能在创建它的线程中访问,在子线程中不能访问。
也就是说,如果你在主线程中new了一个RealmObject对象 user,那么在子线程中是访问不了user对象的。
要想在子线程中访问,必须先将user存入Ream中,然后在子线程中query出来。
简书文章

is not part of the schema for this Realm

详细异常信息: java.lang.IllegalArgumentException: UserBean is not part of the schema for this Realm

需要调整plugin中的顺序,如下:

apply plugin: 'com.android.application'
apply plugin: 'com.bugtags.library.plugin'
apply plugin: 'android-apt'
apply plugin: 'realm-android'
apply plugin: 'com.neenbedankt.android-apt'

{bean}has a primary key, use ‘createObject(Class, Object)’ instead

详细异常信息: io.realm.exceptions.RealmException: ‘UserBean’ has a primary key, use ‘createObject(Class, Object)’ instead.

如果实体中已经通过@PrimaryKey标明了主键,那么想要通过createObject(Class<E>, Object)创建实体对象,则必须传入primaryKeyValue(主键值)

异步查询之坑

1.官方文档介绍 主线程操作Realm会卡顿/阻塞线程
防止ANR
官方表示Realm运行速度很快,足以在主线程运行,而后又表示其实还是会阻塞线程导致偶发的ANR,因此建议在子线程操作Realm.

2.子线程查询的数据,无法在主线程使用

image.png

解决方案:

子线程查询,置换为自己的Bean类,然后在主线程使用.

Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        Person ziPerson = realm.where(Person.class).findFirst();
        personInfo = new PersonInfo();
        personInfo.setName(ziPerson.getName());
        personInfo.setAge(ziPerson.getAge());
        //Log 输出#Execute ] false..Person{name='小明', age=18}
        KLog.i((Looper.getMainLooper()==Looper.myLooper())+".."+ personInfo.toString());
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
        //Log 输出#OnSuccess ] true..personInfo:Person{name='小明', age=18}
        KLog.i((Looper.getMainLooper()==Looper.myLooper())+".."+ personInfo.toString());
    }
}, new Realm.Transaction.OnError() {
    @Override
    public void one rror(Throwable error) {
        KLog.i(error.toString());
    }
});

RejectedExecutionException

详细异常信息:java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@4dffbdd rejected from io.realm.internal.async.RealmThreadPoolExecutor@c09c352[Running, pool size = 17, active threads = 2, queued tasks = 100, completed tasks = 110]

解决方案:

不要在for循环中使用Realm,将数据存入集合中,然后开启事务,直接使用copyToRealmOrUpdate(realmObjectList)存储即可.

事务嵌套报异常

详细异常信息:The Realm is already in a write transaction in /Users/blakemeike/Working/release/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 116

原因 : 在一个事务中开启了另外一个事务.应避免这种情况.

标签:realm,采坑,plugin,Object,RealmObject,线程,Realm,Android
来源: https://blog.csdn.net/wangxw725/article/details/100171404

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有