安卓-ObjectBox数据库笔记3:数据观察者和Rx

(安卓)ObjectBox数据库笔记-数据观察者和Rx

[TOC]

1.订阅一个数据表的变化 DataSubscription DataObserver

让我们从一个示例开始,演示如何使用响应式数据观察者:

// Keep a reference until the subscription is cancelled
// to avoid garbage collection.
private DataSubscription subscription;

// ...
// Build a regular query.
Query<Task> query = taskBox.query().equal(Task_.complete, false).build();
// Subscribe to its results.
subscription = query.subscribe()
    .on(AndroidScheduler.mainThread())
    .observer(data -> updateResultDisplay(data));

// Cancel to no longer receive updates (e.g. leaving screen).
subscription.cancel();
private void updateResultDisplay(List<Task> tasks) {

   // Do something with the given tasks.

}

1.查询是在后台执行的

2.一旦查询完成,观察者就会获得结果数据

3.once updated query results are in, they are propagated to the observer

4..on(AndroidScheduler.mainThread()) 观察者在Android的主线程被调用

数据订阅,在UI更新或其他地方非常有用。

在安卓中,订阅和取消订阅,要在相应的生命周期内相应执行

可执行订阅的生命周期:onCreate()/onStart()/onResume()

可取消订阅的生命周期:onDestroy()/onStop()/onPause().

2.取消多个订阅 DataSubscriptionList

一个Query有一个DataSubscription,一次只能取消一个订阅。一个DataSubscriptionList可以用于多个Query,同时取消多个订阅。

subscriptionList = new DataSubscriptionList();
ObjectBox.get().boxFor(UserEntity.class).query().build().subscribe(subscriptionList).observer(new DataObserver<List<UserEntity>>() {
    @Override
    public void onData(List<UserEntity> data) {
        Log.d(TAG,"subscriptionList 观察到UserEntity表数据变化 size:"+data.size());
    }
});
ObjectBox.get().boxFor(Person.class).query().build().subscribe(subscriptionList).observer(new DataObserver<List<Person>>() {
    @Override
    public void onData(List<Person> data) {
        Log.d(TAG,"subscriptionList 观察到Person表数据变化 size:"+data.size());
    }
});

...
if(subscriptionList!=null && !subscriptionList.isCanceled()) {
    subscriptionList.cancel();
}
...

3.观察者和事务 Observers and Transactions

观察者通知发生在事务提交之后。对于某些场景,了解事务边界特别重要。如果分别调用box.put()或remove(),将启动并提交一个隐式事务。例如,这段代码将在User.class上触发两次数据观察者:

box.put(friendUser);
box.put(myUser);

有几种方法可以将多个操作组合到一个事务中,例如使用BoxStore类中的runInTx()或callInTx()方法之一。对于我们的简单示例,只需使用接受多个对象的put()重载:

box.put(friendUser, myUser);

4.数据转换 Transforming data

subscription = boxStore.subscribe()
    .transform(clazz -> return boxStore.boxFor(clazz).count())
    .observer(count -> updateCount(count));

把查询的结果,转换成另一种对象,例如新的可观察对象?

1.实际上“转换”任何数据都不需要转换。从技术上讲,返回接收到的相同数据并使用(或不使用)它进行一些处理是没问题的。

Transforms are not required to actually “transform” any data. Technically, it is fine to return the same data that is received and just do some processing with (or without) it.

2.Transforms 总是异步执行的。执行持久的操作是很好的。

Transformers are always executed asynchronously. It is fine to perform long lasting operations.

5.ErrorObserver

和transform配合使用,当transform里发生异常时,异常会回调到onError方法里。

public interface ErrorObserver {
    void onError(Throwable th);
}

6.Single Notifications vs. Only-Changes

当您订阅一个查询时,DataObserver在默认情况下会获得以下两个行为

1.初始查询结果(在订阅之后)

2.当数据表有增删改查时,更新查询结果(底层数据已更改)

如果只想查一次,以后的增删改查不继续监听。或者订阅时不需要初始化的结果,只需要监听后面的增删改查怎么处理?

single():只回调初始化查询结果

onlyChanges(): 只订阅以后的增删改查,不需要初始化查询结果

ObjectBox.get().boxFor(UserEntity.class)
        .query()
        .build()
        .subscribe(subscriptionList)
        .on(AndroidScheduler.mainThread())
        .single()
        .observer(new DataObserver<List<UserEntity>>() {
            @Override
            public void onData(List<UserEntity> data) {
                Log.d(TAG, "初始化查询结果single:" + data);
            }
        });

ObjectBox.get().boxFor(UserEntity.class)
        .query()
        .build()
        .subscribe(subscriptionList)
        .on(AndroidScheduler.mainThread())
        .onlyChanges()
        .observer(new DataObserver<List<UserEntity>>() {
            @Override
            public void onData(List<UserEntity> data) {
                Log.d(TAG, " 观察到数据变化onlyChanges:" + data);
            }
        });

7.弱引用 Weak References

Sometimes it may be nice to have a weak reference to a data observer. Note that for the sake of a deterministic flow, it is advisable to cancel subscriptions explicitly whenever possible. If that does not scare you off, use weak() after subscribe().

ObjectBox.get().boxFor(UserEntity.class)
        .query()
        .build()
        .subscribe(subscriptionList)
        .on(AndroidScheduler.mainThread())
        .weak()
        .onlyChanges()
        .observer(new DataObserver<List<UserEntity>>() {
            @Override
            public void onData(List<UserEntity> data) {
                Log.d(TAG, " 观察到User表数据变化onlyChanges:" + data);
            }
        });

8.ObjectBox RxJava扩展库 ObjectBox RxJava Extension Library

它提供了类RxQuery和RxBoxStore。两者都提供了使用RxJava方式进行订阅的静态方法。

对于一般的对象更改,你可以使用RxBoxStore来创建一个可观察对象。

RxBoxStore.observable(ObjectBox.get()).subscribe(new Consumer<Class>() {
    @Override
    public void accept(Class aClass) throws Exception {
        Log.d(TAG, "RxBoxStore.observable(ObjectBox.get()).subscribe");
    }
});

RxQuery允许使用以下方法订阅查询对象:

1.Flowable

2.Observable

3.Single

private Disposable disposable;
// ...
Query query = box.query().build();
disposable = RxQuery.observable(query).subscribe(this);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容