[关闭]
@SmartDengg 2015-12-25T11:23:22.000000Z 字数 2980 阅读 1140

Realm Java 0.87 — with RxJava support!

我们刚刚发布了最新版本的Realm并上传到了Maven。这个第一个支持RxJava的版本。

RxJava

RxJava是Netflix出品的一个扩展了观察者模式响应式框架类库。它让通过组合操作符的方式来改变Realm数据变成了可能。目前除了RealmQueryRealmList以外的其它Realm类都可以转换成Observable.

Realm的Observable建立在标准的RealmChangeListener之上,所以任何Observable发送事件的速率与ChangeListener的通知速率保持一致。

  1. Realm realm = Realm.getDefaultInstance();
  2. RealmResults<Person> persons = realm.where(Person.class).findAll();
  3. Person person = persons.first();
  4. Observable<Realm> realmObservable = realm.asObservable();
  5. Observable<RealmResults<Person>> resultsObservable = persons.asObservable();
  6. Observable<Person> objectObservable = person.asObservable();

同样适用于Realm的异步API:

  1. realm.where(Person.class).equalTo("name", "John").findAllAsync().asObservable()
  2. .filter(new Func1<RealmResults<Person>, Boolean>() {
  3. @Override
  4. public Boolean call(RealmResults<Person> persons) {
  5. // Ignore unloaded results
  6. return persons.isLoaded();
  7. }
  8. })
  9. .subscribe(new Action1<RealmResults<Person>>() {
  10. @Override
  11. public void call(RealmResults<Person> persons) {
  12. // Show persons...
  13. }
  14. });

更多用例请阅读RxJava example project

配置

尽管RxJava在我们的API中能够表现良好,但它始终是个opt-in依赖,这就意味着需要在build.gradle中手动添加RxJava依赖。这样做的好处就是完全由你决定使用RxJava的哪个版本,并且能够在不需要使用RxJava的项目中避免方法数量溢出的问题。

  1. dependencies {
  2. compile 'io.realm:realm-android:0.87.0'
  3. compile 'io.reactivex:rxjava:1.1.0'
  4. }

我们为那些想自定义创建Observable方式的同学提供了一个叫做RxObservableFactory的新接口。可以使用RealmConfiguration配置自定义factory,但是Realm自带一个默认RealmObservableFactory,只能在RxJava 1.1.*以下使用。

  1. RealmConfiguration config = new RealmConfiguration.Builder(context)
  2. .rxFactory(new MyFactory())
  3. .build()

开发中版本

现在我们只是实现了对RxJava的初步支持,遗憾的是仍不支持将RealmQueryRealmList转换成Observable。不过这些新特性将被添加到以后的更新中。

需要特别记住的是RealmObjectRealmResults是受线程约束的。这就意味着不能在一个线程中加载Realm对象而在另一个线程中使用。

  1. // Default pattern for loading data on a background thread
  2. Observable.defer(new Func0<Observable<RealmResults<Person>>>() {
  3. @Override
  4. public Observable<RealmResults<Person>> call() {
  5. return realm.where(Person.class).findAll().asObservable();
  6. }
  7. })
  8. .subscribeOn(Schedulers.io())
  9. .observeOn(AndroidSchedulers.mainThread())
  10. .subscribe(new Action1<RealmResults<Person>>() {
  11. @Override
  12. public void call(RealmResults<Person> persons) {
  13. // Accessing persons here would crash.
  14. }
  15. });
  16. // Instead, use Realms Async API for the same effect
  17. realm.where(Person.class).findAllAsync().asObservable()
  18. .subscribe(new Action1<RealmResults<Person>>() {
  19. @Override
  20. public void call(RealmResults<Person> persons) {
  21. // Show data in the UI
  22. }
  23. });

RealmObjectRealmResult都是活动对象,也就是说它们会不断地更新从而与Realm中的最新数据保持一致。这种一致性真的很伟大,但是目前还不支持不可变的线程安全对象,因此不能与RxJava模型友好的协同工作。所以,我们又添加了Realm.copyFromRealm()方法,它可以将Realm数据复制到标准Java对象中,把它们有效地从Realm中分离出来。虽然会造成一定的延迟和内存开销,但是这样做就能够更容易的与操作符一起工作了,比如.buffer()

  1. // Get different versions of a person
  2. realm.where(Person.class).findFirst().<Person>asObservable()
  3. .map(new Func1<Person, Person>() {
  4. @Override
  5. public Person call(Person person) {
  6. // Convert live object to a static copy
  7. return realm.copyFromRealm(person);
  8. }
  9. })
  10. .buffer(2)
  11. .subscribe(new Action1<List<Person>>() {
  12. @Override
  13. public void call(List<Person> persons) {
  14. // Without `map` and `copyFromRealm`, v1 and v2 would be the same
  15. Person v1 = persons.get(0);
  16. Person v2 = persons.get(1);
  17. }
  18. });

更好的解决方案将被添加到未来的更新中。

了解所有细节请查看完整的更新日志

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注