Skip to content
On this page

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

修饰符

@Required 不能为空的字段

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

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

@PrimaryKey 主键

自动更新

RealmObjectRealmResults 在数据库变动的时候会自动更新,可通过 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异步消息处理机制完全解析,带你从源码的角度彻底理解