防止更改多个表时触发多个房间的可观察房间的查询

问题描述 投票:0回答:1

我在Android Room中使用可观察的查询来触发更新,这些更新最终会在基础数据发生更改时更改UI。

有时这些查询涉及多个表,有时用户执行将新值插入这些表的操作。通常,插入操作非常快速地完成(即在不到一半的时间间隔内)]

[当前,从Room订阅更新的观察者将被触发x次,其中x是查询中已更新的表数。

因此,如果将值彼此之间在一秒钟内全部插入查询的六个不同表中,则观察该查询的任何观察者将触发六次。

是否有办法告诉Room; “仅触发观察者每秒最多一次”?或者,更好的方法是“当您看到更新时,请等待半秒钟以收集其他任何更新,然后立即将所有内容通知观察者”?

这里是会议室查询。如您所见,其中涉及多个表。

 @Query("SELECT Distinct order_material.* FROM order_material" +
            " JOIN orders on order_material.orderId = orders.id" +
            " JOIN assignment on order_material.id = assignment.orderMaterialID" +
            " JOIN box_inside on assignment.boxInsideID = box_inside.id" +
            " WHERE orders.isActive = 1 " +
            " AND (box_inside.dateCFOrigPacked <= :dateLimitYema OR box_inside.stemLength IS NOT NULL)" +
            " AND assignment.id IN (SELECT id FROM assignment WHERE active = 1" +
            "      AND quantity > 0 AND assignment.id NOT IN "+
            "              (Select assignmentID FROM " +
            "               (Select assignmentID, assignment.quantity as sum_assign, SUM(preparation.quantityPrepared) as sum_prep " +
            "               from preparation "  +
            "               JOIN assignment on preparation.assignmentID = assignment.id"  +
            "               GROUP BY preparation.assignmentID " +
            "               HAVING sum_assign <= sum_prep)))" +
            " Order By order_material.deliveryDate ASC")
    Observable<OrderMaterial[]> getOrderMaterialsReadyToPrepareAsync(Date dateLimitYema);

这里是观察查询的存储库方法。它被触发X次,其中X是在很短的时间内更新的表数。

 public Observable<List<OrderMaterial>> findOrderMaterialsReadyToPrepareAsync(){
        int daysInOneWeek = 7;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -1 * daysInOneWeek);
        Date limitOneWeekYemas = calendar.getTime();

        return Observable.create(subscribe ->
            assignmentDao.getOrderMaterialsReadyToPrepareAsync(limitOneWeekYemas)
                    .observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
                    .subscribe(new Observer<OrderMaterial[]>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Timber.v("findOrderMaterialsReadyToPrepareAsync on subscribe");
                            subscribe.setDisposable(d);
                            preparationDisposable.add(d);
                        }

                        @Override
                        public void onNext(OrderMaterial[] materials) {
//                            Timber.v("findOrderMaterialsReadyToPrepareAsync onNext with %s", Arrays.toString(materials));
                            subscribe.onNext(Arrays.asList(materials));
                        }

                        @Override
                        public void onError(Throwable e) {
                            Timber.e(e,"findOrderMaterialsReadyToPrepareAsync onError");
                            subscribe.onError(e);
                        }

                        @Override
                        public void onComplete() {
                            Timber.e("findOrderMaterialsReadyToPrepareAsync onComplete");
                        }
                    })
        );
    }
android-room rx-java2
1个回答
0
投票

是否有办法告诉Room; “仅触发观察者每秒最多一次”?或者,更好的方法是“当您看到更新时,请等待半秒钟以收集其他任何更新,然后立即将所有内容通知观察者”?

据我所知,还没有与Room交流的方法。后台的Room中可观察到的查询(使用LiveData,RxJava,Flow)使用DB's InvalidationTracker调用(就像一个简单的任何更改触发器):

将给定的观察者添加到观察者列表中,如果它观察到的任何表发生更改,都将得到通知。

不仅如此,即使您以某种条件(例如select * from users where id =:id)观察(使用Observables之一)查询,即使更改了该特定ID的表的行没有变化,也会在每张表更改后得到通知。

您可以尝试将@Transaction添加到查询中(仅触发一个),但我想这无济于事。

因此,我认为您不应该期望Room从这方面获得太多的情报。然后,如果您使用RxJava,则它是期望进行此类智能“对话”的第一个候选对象(可以选择debounce运算符)。

© www.soinside.com 2019 - 2024. All rights reserved.