重大更改列表可在其 Github 上的 CHANGELOG.MD 中找到。
但是,值得注意的是,在开发过程中发生了很多重大变化,尤其是 0.89.0。
从0.82.0到5.1.0如下(目前最稳定的版本):
0.82.0:
重大更改:带有注释 @PrimaryKey 的字段现在会自动编入索引。旧架构需要迁移。
(0.82.2 在这里是最稳定的,但它在 Blackberry 设备上不起作用。在 Blackberry 上使用的第一个 stable 版本是 0.87.2。)
在 0.86.0+ 中,您可以使用
向带注释的字段添加索引
@Override
public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
RealmSchema schema = realm.getSchema();
// version check and stuff
RealmObjectSchema personSchema = schema.get("Person");
personSchema.addIndex("fieldName");
0.83:
重大更改:数据库文件格式更新。此版本创建的Realm文件不能被之前版本的Realm使用。
重大变化:从 Realm 类中删除了不推荐使用的方法和构造函数。
重大变化:引入了盒装类型 Boolean、Byte、Short、Integer、Long、Float 和 Double。添加了空支持。引入注解 @Required 以指示字段不可为空。默认情况下,String、Date 和 byte[] 可以为空,这意味着如果打开以前版本的 Realm 文件,将引发 RealmMigrationNeededException。
哦,男孩,这是一个不错的选择。 NULL 支持。
原语的盒装类型变得可用。默认情况下,盒装类型可以为空。所有String、Date 和byte[] 都必须使用@Required 或schema.setNullable("fieldName", nullability) 进行注释,并使它们都可以为空。
0.84.0:
添加了异步查询。就架构而言,这里没有什么新东西。
0.85.0:
重大更改:删除 RealmEncryptionNotSupportedException,因为 Realm 的底层存储引擎中的加密实现发生了变化。现在所有设备都支持加密。
重大更改:Realm.executeTransaction() 现在直接抛出任何 RuntimeException 而不是将其包装在 RealmException (#1682) 中。
重大更改:如果字段名是链接字段且最后一个元素是链接,则 RealmQuery.isNull() 和 RealmQuery.isNotNull() 现在会抛出 IllegalArgumentException 而不是 RealmError (#1693)。
这里还没有什么重要的,虽然:
如果值包含无效(非托管、删除、关闭、来自不同领域)对象 (#1749),RealmObject 和 RealmList 的托管对象中的设置器现在会抛出 IllegalArgumentException。
这个很有趣。以前它只是失败了,所以这是最好的。但这也是 Realm 最大的限制。
0.86.0:
重大更改:迁移 API 已被新 API 替换。
重大更改:RealmResults.SORT_ORDER_ASCENDING 和 RealmResults.SORT_ORDER_DESCENDING 常量已替换为 Sort.ASCENDING 和 Sort.DESCENDING 枚举。
重大更改:RealmQuery.CASE_SENSITIVE 和 RealmQuery.CASE_INSENSITIVE 常量已替换为 Case.SENSITIVE 和 Case.INSENSITIVE 枚举。
重大更改:Realm.addChangeListener、RealmObject.addChangeListener 和 RealmResults.addChangeListener 持有对侦听器的强引用,您应该注销侦听器以避免内存泄漏。
重大更改:删除了已弃用的方法 RealmQuery.minimum{Int,Float,Double}、RealmQuery.maximum{Int,Float,Double}、RealmQuery.sum{Int,Float,Double} 和 RealmQuery.average{Int,Float,双倍的}。请改用 RealmQuery.min()、RealmQuery.max()、RealmQuery.sum() 和 RealmQuery.average()。
重大更改:删除了错误公开的 RealmConfiguration.getSchemaMediator()。并添加 RealmConfiguration.getRealmObjectClasses() 作为替代方法,以获取模型类集 (#1797)。
重大更改:Realm.addChangeListener、RealmObject.addChangeListener 和 RealmResults.addChangeListener 在非 Looper 线程上调用时会抛出 IllegalStateException。这是为了防止注册不会被调用的监听器。
使用 DynamicRealm 和 DynamicRealmObject 添加了新的动态 API。
添加了 Realm.getSchema() 和 DynamicRealm.getSchema()。
new Migration API, using DynamicRealm instead of Realm.getTable()。
有些东西被重命名了,如果你的结果集仍然有效,你应该取消注册你的更改监听器。但值得注意的是,您仍然应该为您的RealmResults 保留一个字段变量,因为Realm 的Context 对它只有一个弱引用。
0.87.0:
RX 支持。没什么重要的。
0.87.2:
在提交事务时移除显式 GC 调用 (#1925)。
终于,Realm 又稳定了! :)
0.88.0:
重大变化
Realm 现在必须作为 Gradle 插件安装。
DynamicRealm.executeTransaction() 现在直接抛出任何 RuntimeException 而不是将其包装在 RealmException 中 (#1682)。
DynamicRealm.executeTransaction() 现在会抛出 IllegalArgumentException 而不是静默接受 null Transaction 对象。
对于无效代理,字符串设置器现在抛出 IllegalArgumentException 而不是 RealmError。
DynamicRealm.distinct()/distinctAsync() 和 Realm.distinct()/distinctAsync() 现在针对无效类型或未索引字段抛出 IllegalArgumentException 而不是 UnsupportedOperationException。
所有线程本地更改侦听器现在都延迟到下一个 Looper 事件,而不是在提交时被触发。
从 0.86.0 中已弃用的公共 API 中删除了 RealmConfiguration.getSchemaMediator()。请使用 RealmConfiguration.getRealmObjectClasses() 获取模型类集(#1797)。
如果 Realm 文件不存在,Realm.migrateRealm() 会抛出 FileNotFoundException。
现在需要取消订阅所有 Realm RxJava observables 才能完全关闭 Realm (#2357)。
很好。现在是 AAR。您必须添加到 classpath 并使用 apply plugin: 'realm-android' 而不是 compile ... 依赖项运行它。
仅在下一个事件循环时调用更改侦听器,而不是在提交后立即调用。我.. 老实说,我并不完全确定这会产生什么后果,但这意味着更改侦听器不适用于后台线程。仅在 Looper 线程(主要是 UI 线程)上。
增强功能
支持自定义方法、访问器中的自定义逻辑、自定义访问器名称、接口实现和 Realm 对象中的公共字段 (#909)。
使用 ReLinker 改进了 .so 加载。
虽然这是非常必要的,所以我肯定不想卡在 0.87.5 上。
0.89.0:
重大变化
@PrimaryKey 字段值现在可以为 String、Byte、Short、Integer 和 Long 类型的 null。应该使用 RealmObjectSchema.setNullable() 或通过添加 @Required 注释来迁移较旧的领域。 (#2515)。
RealmResults.clear() 现在抛出 UnsupportedOperationException。请改用 RealmResults.deleteAllFromRealm()。
RealmResults.remove(int) 现在抛出 UnsupportedOperationException。请改用 RealmResults.deleteFromRealm(int)。
RealmResults.sort() 和 RealmList.sort() 现在返回排序后的结果,而不是就地排序。
如果 RealmList 为空,RealmList.first() 和 RealmList.last() 现在会抛出 ArrayIndexOutOfBoundsException。
从公共 API 中删除了已弃用的方法 Realm.getTable()。
Looper 上的 Realm.refresh() 和 DynamicRealm.refresh() 不再有任何效果。 RealmObject 和 RealmResults 总是在下一个事件循环中更新。
好吧,这个是最乱的一个。
1.) 您必须为@PrimaryKey 注释字段添加@Required 注释,因为null 是有效的主键值。
2.) realm.refresh() 不再有效。无论如何它都会被删除。不过,这里有一个workaround for 1.1.1,应该只在后台线程上使用。不过,它在 Realm 3.2 中再次可用。
3.) getTable() 被删除。不要使用它。使用新的迁移 API。
4.) realmResults.sort() 返回一个新的 RealmResults,它也需要附加更改侦听器。我认为它不可靠,所以我只使用findAllSorted()。
5.) 你可能不会想太多,但是
RealmObject 和 RealmResults 总是在下一个事件循环中更新。 (注意:这不再是真实的,因为 REALM 3.1+ 在 commitTransaction() 上再次调用更改侦听器)
这实际上意味着 RealmResults 仅在事件循环发生时更新,而不是在您调用 realm.commitTransaction() 时立即更新。这也意味着在后台线程上,当您commitTransaction() 时,RealmResults 没有更新,您必须重新查询它们。
RealmResults 只有在调用附加的RealmChangeListener 后才会更新。在 1.1.1 中,当调用 RealmChangeListener 时,所有结果都已更新。
然而,这一变化也改变了事务中的迭代行为。在交易中,您总是看到最新版本。这意味着在您对其进行迭代和修改元素时,会重新评估查询。 (这也是 REALM 3.0 以来的情况)
例如,以前这是有效的代码:
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
while(!stuffs.isEmpty()) {
stuffs.get(0).setSomething(true);
}
// you end up here because stuffs will be empty
// because of live auto-updates in transactions
但是,这将不再有效。对我来说,这会导致问题,因为我有时会这样迭代
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(int i = 0; i < stuffs.size(); i++) {
stuffs.get(i--).setSomething(true);
}
// I end up here because of live auto-updates
这是一个问题,因为stuffs 将不再更改。我必须在我的代码中搜索 -- 并像这样修复所有迭代。
以前的官方解决方法是这样的:
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(int i = stuffs.size()-1; i >= 0; i--) {
stuffs.get(i).setSomething(true);
}
// I end up here because of normal iteration
这在 0.89.0 中仍然可以正常工作。
从 0.89.0 开始,这也是有效代码(在 3.0.0+ 中,这会自动创建快照集合):
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(Stuff stuff : stuffs) {
stuff.setSomething(true);
}
虽然结果中的元素仍然无效,但结果本身不会改变。 (在 Realm 3.0.0+ 中,快照集合也是如此)。
0.90.0:
重大变化
RealmChangeListener 也提供更改后的对象/领域/集合 (#1594)。
Realm 上的所有 JSON 方法现在只将 JSONException 包装在 RealmException 中。所有其他异常都按原样抛出。
将 RealmObject 上的所有方法和所有公共类标记为 final (#1594)。
从公共 API 中移除 BaseRealm。
从公共 API 中移除 HandlerController。
从公共 API (#1594) 中删除了 RealmAsyncTask 的构造函数。
RealmBaseAdapter 已移至其自己的 GitHub 存储库:https://github.com/realm/realm-android-adapters
Realm 文件的文件格式已更改。文件将自动升级,但无法使用旧版本的 Realm 打开 Realm 文件。
所以RealmBaseAdapter 现在在realm-android-adapters 中,对于Realm 的1.1.1,使用1.3.0。还添加了RealmRecyclerViewAdapter。对于3.5.0,请使用2.0.0 或更新版本。
RealmChangeListeners 有一个element 参数。耶。
此外,日期现在具有milisecond 精度。
0.91.0:
重大变化
删除了所有@Deprecated 方法。
即使 autoRefresh 为 false (#2820),从非 Looper 线程调用 Realm.setAutoRefresh() 或 DynamicRealm.setAutoRefresh() 也会引发 IllegalStateException。
在0.90.0中弃用了很多方法,所以
重大变化:
Realm.allObjects*()。请改用 Realm.where(clazz).findAll*()。
Realm.distinct*()。请改用 Realm.where(clazz).distinct*()。
DynamicRealm.allObjects*()。请改用 DynamicRealm.where(className).findAll*()。
DynamicRealm.distinct*()。请改用 DynamicRealm.where(className).distinct*()。
Realm.allObjectsSorted(字段,排序,字段,排序,字段,排序)。请改用 RealmQuery.findAllSorted(field[], sort[])`。
RealmQuery.findAllSorted(字段,排序,字段,排序,字段,排序)。请改用 RealmQuery.findAllSorted(field[], sort[])`。
RealmQuery.findAllSortedAsync(字段,排序,字段,排序,字段,排序)。请改用 RealmQuery.findAllSortedAsync(field[], sort[])`。
RealmConfiguration.setModules()。请改用 RealmConfiguration.modules()。
Realm.refresh() 和 DynamicRealm.refresh()。请改用 Realm.waitForChange()/stopWaitForChange() 或 DynamicRealm.waitForChange()/stopWaitForChange()。
waitForChange() 并没有像人们打算使用的那样真正起作用,所以这里有一个workaround for 1.1.1 to 3.1.4,但应该只在后台线程上使用。 refresh() 将在 3.2.0 中重新添加。
此外,在某些时候 Realm.getInstance(Context) 已被删除,请改用 Realm.getInstance(new RealmConfiguration.Builder(Context).build())。
之后,1.0.0 来了,差不多就是这样。
顺便说一句,在 1.1.0 中,添加了 insertOrUpdate(),它比 copyToRealmOrUpdate() 更快,并且不返回代理。
2.0.2:
主键在托管对象上是不可变的,一旦设置,就无法更改,如果您尝试,它会引发异常。另外,如果您使用createObject() 创建对象,请使用realm.createObject(clazz, primaryKeyValue)。
您必须在某个时候致电Realm.init(Context)。
配置生成器不再接收上下文。
armeabi 不再受支持。 (仅 v7a 和其他)
在 3.0.0 之前没有重大更改,但有大量错误修复。
3.0.0:
RealmResults.distinct() 返回一个新的 RealmResults 对象,而不是对原始对象进行过滤 (#2947)。
RealmResults 会不断自动更新。当前线程上任何可能影响 RealmResults 的顺序或元素的事务都将立即更改 RealmResults,而不是在下一个事件循环中更改它。标准 RealmResults.iterator() 将继续正常工作,这意味着您仍然可以删除或修改元素而不会影响迭代器。对于简单的 for 循环,情况并非如此。在某些情况下,简单的 for 循环不起作用 (https://realm.io/docs/java/3.0.0/api/io/realm/OrderedRealmCollection.html#loops),您必须使用新的 createSnapshot() 方法。
RealmObject 上的 RealmChangeListener 现在也会在删除对象时触发。使用 RealmObject.isValid() 来检查这个状态(#3138)。
RealmObject.asObservable() 现在将在删除对象时发出该对象。使用 RealmObject.isValid() 来检查这个状态 (#3138)。
删除了已弃用的类 Logger 和 AndroidLogger (#4050)。
由于 Realm ObjectStore Results 集成,RealmResults 在事务中再次活动,就像在 0.88.3 及之前的版本一样。
所以simple for loops(使用for(int i = 0; ... 进行索引)很容易中断 -
这意味着您要么需要对它们进行反向迭代,要么先创建一个快照集合。
OrderedRealmCollection<Thing> snapshot = results.createSnapshot();
for(int i = 0; i < snapshot.size(); i++) { ...
此外,RealmObject 更改侦听器现在也会在删除时发出,您需要在更改侦听器中检查 isValid()。这样您就可以在后台删除对象时更新 UI。
3.1.0:
更新了 Realm 文件的文件格式。现有的 Realm 文件在打开时会自动迁移到新格式,但旧版本的 Realm 无法打开这些文件。
这里没什么可做的,但值得一提。
3.2.0-3.2.1:
这里没什么可做的,除了更新proguard,因为这里引入了一个bug。添加了 proguard 部分。
3.3.0:(和 3.3.1)
这里没什么可做的,修复了3.2.0中导致Proguard问题的bug。
3.4.0:
这里没什么可做的,尽管值得研究用于反向关系的新 @LinkingObjects API。
其实还是建议用单向链接+反向关系代替双向链接。
3.5.0:
重大变化
如果给定的 RealmModule 不包含所有必需的模型类 (#3398),则会引发 IllegalStateException。
如果您没有在modules() 中指定所有 RealmObjects(如果您使用多个模块而不是仅使用默认模块,例如库项目中的 RealmObjects),那么您需要确保您确实提供了所有 RealmObjects是模块中架构的一部分。
以前它会默默地添加它们,即使它们不在模块中,现在情况并非如此。
4.0.0:
重大变化
内部文件格式已升级。打开一个旧的领域
将自动升级文件,但旧版本的 Realm 会
不再能够读取该文件。
[ObjectServer] 将协议版本更新为仅兼容的 22
使用领域对象服务器 >= 2.0.0。
[ObjectServer] 已移除已弃用
API SyncUser.retrieveUser() 和 SyncUser.retrieveUserAsync()。采用
改为 SyncUser.retrieveInfoForUser() 和 retrieveInfoForUserAsync()。
[ObjectServer] SyncUser.Callback 现在接受通用参数
指示调用 onSuccess 时返回的对象类型。
[ObjectServer] 将 SyncUser.getAccessToken 重命名为
SyncUser.getRefreshToken。
[ObjectServer] 删除了不推荐使用的 API
SyncUser.getManagementRealm()。
在排序后调用 distinct()
RealmResults 不再清除任何已定义的排序 (#3503)。
放松
RealmList、RealmQuery、RealmResults 类型参数的上限,
RealmCollection、OrderedRealmCollection 和
OrderedRealmCollectionSnapshot。
Realm 升级了对 RxJava1 的支持
到 RxJava2 (#3497) Realm.asObservable() 已重命名为
领域.asFlowable()。 RealmList.asObservable() 已重命名为
RealmList.asFlowable()。 RealmResults.asObservable() 已重命名
到 RealmResults.asFlowable()。 RealmObject.asObservable() 已
重命名为 RealmObject.asFlowable()。 RxObservableFactory 现在返回
RxJava2 类型而不是 RxJava1 类型。
删除了已弃用的 API
RealmSchema.close() 和 RealmObjectSchema.close()。那些不必
不再被称为。
删除了已弃用的 API
RealmResults.removeChangeListeners()。采用
RealmResults.removeAllChangeListeners() 代替。
已删除已弃用
API RealmObject.removeChangeListeners()。采用
RealmObject.removeAllChangeListeners() 代替。
已移除
UNSUPPORTED_TABLE、UNSUPPORTED_MIXED 和 UNSUPPORTED_DATE 从
领域字段类型。
删除了已弃用的 API
RealmResults.distinct()/RealmResults.distinctAsync()。采用
改为 RealmQuery.distinct()/RealmQuery.distinctAsync()。
RealmQuery.createQuery(Realm, Class),
RealmQuery.createDynamicQuery(DynamicRealm, String),
RealmQuery.createQueryFromResult(RealmResults) 和
RealmQuery.createQueryFromList(RealmList) 已被删除。采用
Realm.where(Class)、DynamicRealm.where(String)、RealmResults.where()
和 RealmList.where() 代替。
所以 Rx1 支持被 Rx2 支持取代,removeChangeListeners() 被重命名为 removeAllChangeListeners()。
大多数其他事情只会影响同步领域,从这一点开始,可以使用 RealmList<String>、RealmList<Date> 和 RealmList<Integer> 作为领域架构的一部分。暂不支持查询,create*FromJson方法不填写。
4.3.1:
已弃用
RealmQuery.findAllSorted() 和 RealmQuery.findAllSortedAsync()
支持谓词 RealmQuery.sort().findAll() 的变体。
支持 RealmQuery.distinct() 和 RealmQuery.distinctAsync() 变体
谓词 RealmQuery.distinctValues().findAll()
您现在可以使用 realm.where(Blah.class).distinct("something") 或 realm.where(Blah.class).findAllSorted("something"),而不是使用
realm.where(Blah.class)
.distinctValues("something") // subject to change to `distinct()`
.sort("something") // hopefully will change to `sorted()`? // nope, it's `sort`
.findAll();
5.0.0:
将 RealmQuery.distinctValues() 重命名为 RealmQuery.distinct()
删除了以前弃用的 RealmQuery.findAllSorted()、RealmQuery.findAllSortedAsync() RealmQuery.distinct() 和 RealmQuery.distinctAsync()`。
OrderedRealmCollectionChangeListener.onChange() 中的 OrderedCollectionChangeSet 参数不再可以为空。请改用 changeSet.getState() (#5619)。
所以这意味着realm.where(...).findAllSorted("field") 应该是realm.where(...).sort("field").findAll()。
还有 OrderedRealmCollectionChangeListener 曾经发送 null 作为初始更改集,现在不再是这种情况,== null 应该替换为 .getState() == OrderedCollectionChangeSet.State.INITIAL。这也意味着您需要在 Realm 5.0+ 中使用realm-android-adapters 3.0.0 或更新版本。
此外,如果您依赖于 __RealmProxy 类的名称:它们将以其完全限定名称命名,包括包,例如 my_package_SomeObjectRealmProxy。
保护规则
#realm older than 0.84.1
-keepnames public class * extends io.realm.RealmObject
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.** { *; }
-dontwarn javax.**
-dontwarn io.realm.**
#realm 0.84.1+ and older than 1.0.0
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-dontwarn javax.**
-dontwarn io.realm.**
#realm 0.89.0+ and older than 1.0.0
-keep class io.realm.RealmCollection
-keep class io.realm.OrderedRealmCollection
#realm 3.2.0 and 3.2.1
-keepnames public class * extends io.realm.RealmObject