Skip to content
On this page

看 Realm 的文档,为了避免需要时再去整篇文档搜寻一番,在这里做一些记录。

修饰符 ​

@Required 不能为空的字段

@Ignore 不会被保存到 Realm 的字段

@Index 为字段添加索引,写入变慢、文件体积增加

@PrimaryKey 主键

自动更新 ​

RealmObject 和 RealmResults 在数据库变动的时候会自动更新,可通过 addChangeListener() 监听事件。

只有托管对象才有自动更新功能,原始对象并没有!!

为避免在遍历列表时被自动更新影响,可以通过 createSnapshot 创建快照。

主键 ​

Realm.createObject() 会返回一个字段都是默认值的对象,包括主键,所以建议先创建一个非托管对象设置主键然后调用 copyToRealmOrUpdate() 创建托管对象。

声明 Realm 数据模型 ​

继承 RealmObject

实现 RealmModel 接口

关系 ​

RealmObject 之间的关联并不会消耗太多系统开销。

可以使用 RealmList 实现多对多关系,甚至是递归关系。其 getter() 永远返回一个 RealmList 对象。

关联查询 ​
java
realm.where(Person.class).equalTo("dogs.color", "Brown").findAll()
  .equalTo("dogs.age", 1).findAll(); // 在上面的查询结果下继续查
事务 ​

读取事务是隐式的,写入事务是显式的,所有写操作都必须包含在事务内。

事务可以取消,事务之间会阻塞,所以避免在 UI 线程和后台线程同时使用写入事务。

读取事务不会被写入事务阻塞,并且在写入事务完成后会自动刷新没个 Realm 对象。所以,推荐使用一个大的写入事务而不是多个小的写入事务。

异步事务 ​
java
RealmAsyncTask realmAsyncTask = realm.executeTransactionAsync(写入操作,成功回调,错误回调);

回调函数是通过 Looper 被执行的,在非 Looper 线程中只能传入 null.

在退出时应检查 realmAsyncTask 是否已被取消,从而避免 crash.

查询 ​

Realm 中的所有读取(包括查询)操作都是延迟执行的,且数据绝不会被拷贝。

删除对象时,为避免在迭代时崩溃,应选用 realmList.deleteFromRealm(index) 而不是 realm.deleteFromRealm()。

一般情况下可以直接在 UI 线程进行查询操作,但在涉及非常复杂的操作或大量数据的时候也可以选用异步查询,findAllAsync() 会在后台获取数据之后更新之前返回的 RealmResults 对象,可以使用 result.isLoaded() 检查是否完成。

Realms ​

在调用 Realm 实例之前,需要且只需要调用一次 Realm.init(ctx) 方法初始化。之前可通过 Realm.getInstance(ctx) 获取 Realm 实例,同一个线程同一个数据库文件会返回同一个实例。

关闭 Realm 实例 ​

在使用完毕之后请务必关闭实例,以释放 native 内存和文件描述符。

由于 Realm 实例是基于引用计数的,所以调用多少次 getInstance() 就需要关闭多少次。

JSON ​

可以通过 Realm.createOjbectFromJson() 和 Realm.createAllFromJson() 将 JSON 对象直接添加到 Realm 中,包括 String、JSONObject、InputStream。

通知 ​

RealmChangeListener 在任何数据发生变化的时候触发。

OrderedRealmCollectionChangeListener 在集合发生变化的时候触发,参数包含增删改的范围。

RealmObjectChangeListener 在对象发生变化时触发,参数包含改变的字段。

懒加载 ​

Realm 跳过了整个拷贝过程,因为数据库文件是 memory-mapped。Realm 只需要简单计算偏移来找到文件中的数据,然后从原始访问点返回数据结构。

Looper ​

在线程中通过 Looper.prepare() 为线程设定一个唯一的 Looper ,用于轮循处理由 Handler 发来的消息。

kotlin
private val mHandler = Handler(Handler.Callback { msg: Message ->
    when (msg.what) {
        SCAN_OK -> true
        else -> false
    }
})

looper.png

参考 ​

Realm Java 文档

Realm Java 原理介绍以及常见问题

Android异步消息处理机制完全解析,带你从源码的角度彻底理解