当前位置: 首页 > 知识库问答 >
问题:

在可观察结果RxJava之后运行DB Update方法

周培
2023-03-14

应用程序:我有一个非常基本的应用程序,它有一些机器(名称、id、total\u income)和一些收入(id、money、note、Machines\u id)。在第一个屏幕上,我允许用户从一个工厂添加一台机器,然后我将其显示在RecyclerView中。当用户单击任何一台机器时,我将其导航到第二个屏幕,在那里用户可以看到机器的名称、总收入和一个RecyclerView及其相应的收入;有一家工厂可以让他们为那台机器增加收入,并刷新RecyclerView。

问题是:我一直未能将传统世界转换为RxJava。

我已经设法使它工作使用的房间。allowMainThreadQueries()和常规方法。

机器设备模型

public long updateByID(long id, double total_income){
    return machinesDB.getMachineDAO().updateMachineByID(id, total_income);
}

机械DAO

@Query("update machines set total_income = :total_income where id = :id")
int updateMachineByID(long id, double total_income);

MachineInfo活动

disposable.add(incomeViewModel.getIncomeOfMachine(id)
             .defaultIfEmpty(0.0)
             .subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe(total_amount -> {
                     if (total_amount != null) {
                        // This works correctly using .allowMainThreadQueries() and conventional methods
                        machineViewModel.updateByID(id, total_amount);

                        DecimalFormat formatter = new DecimalFormat("$#,##0.000");
                        String formatted = formatter.format(total_amount);
                        mMoney.setText(formatted);

                        Toast.makeText(this, "MachineInfo: " + String.valueOf(machineViewModel.updateByID(id, total_amount)), Toast.LENGTH_SHORT).show();

                         showMenu = true;
                     } else {
                         mMoney.setText("$0.0");
                     }
             }, throwable -> Log.e(TAG, "MachineInfo: ERROR", throwable )));

我知道Room需要在后台线程中实例化,这就是我使用RxJava的原因。但是,当我尝试将上述方法转换为RxJava世界时,就像下面的方法一样,我没有更新,但没有崩溃,“从未使用该方法的返回值”。

机器设备模型

public Completable updateByID(long id, double total_income){
    return Completable.fromAction(() -> machinesDB.getMachineDAO().updateMachineByID(id, total_income));
}

机械DAO

@Query("update machines set total_income = :total_income where id = :id")
int updateMachineByID(long id, double total_income);

尝试#1:失败

private PublishSubject<Double> publishSubject = PublishSubject.create();
private Observable<Double> clickEvent = publishSubject;

/*
/ other stuff in here
*/

disposable.add(incomeViewModel.getIncomeOfMachine(id)
            .defaultIfEmpty(0.0)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(total_amount -> {
                        if (total_amount != null) {

                            publishSubject.onNext(total_amount);

                            DecimalFormat formatter = new DecimalFormat("$#,##0.000");
                            String formatted = formatter.format(total_amount);
                            mMoney.setText(formatted);
                            showMenu = true;
                        } else {
                            mMoney.setText("$0.0");
                        }
                    }, throwable -> Log.d(TAG, "MachineInfo: ERROR")));

    disposable.add(clickEvent.subscribe(
            total_amount -> machineViewModel.updateByID(id, total_amount)));

尝试#2:失败

机器设备模型

public Completable updateByID(long id, double total_income){
    return Completable.fromCallable(() -> machinesDB.getMachineDAO().updateMachineByID(id, total_income));
}

机械DAO

@Query("update machines set total_income = :total_income where id = :id")
int updateMachineByID(long id, double total_income);

MachineInfo活动

disposable.add(incomeViewModel.getIncomeOfMachine(id)
             .defaultIfEmpty(0.0)
             .subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe(total_amount -> {
                     if (total_amount != null) {
                        // Completable.fromCallable()
                        machineViewModel.updateByID(id, total_amount);

                        DecimalFormat formatter = new DecimalFormat("$#,##0.000");
                        String formatted = formatter.format(total_amount);
                        mMoney.setText(formatted);

                        Toast.makeText(this, "MachineInfo: " + String.valueOf(machineViewModel.updateByID(id, total_amount)), Toast.LENGTH_SHORT).show();

                         showMenu = true;
                     } else {
                         mMoney.setText("$0.0");
                     }
             }, throwable -> Log.e(TAG, "MachineInfo: ERROR", throwable )));

共有2个答案

葛成双
2023-03-14

好吧,多亏了迈克尔,我才找到了问题的症结所在。

所以很明显,你可以在一次性用品中添加一次性用品。

>

  • 您需要初始化可观察对象并添加其。观察(等)。订阅(等)。订阅(etc)“
  • 将一次性用品添加到一次性用品中,如下所示:

    disposable.add(incomeViewModel.getIncomeOfMachine(id)
            .defaultIfEmpty(0.0)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(total_amount -> {
                        if (total_amount != null) {
    
                            disposable.add(machineViewModel.updateByID(id, total_amount)
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(
                                            () -> Log.d(TAG, "MachineInfo: COMPLETED"),
                                            throwable -> Log.e(TAG, "MachineInfo: ERROR", throwable )));
    
                            DecimalFormat formatter = new DecimalFormat("$#,##0.000");
                            String formatted = formatter.format(total_amount);
                            mMoney.setText(formatted);
                            showMenu = true;
                        } else {
                            mMoney.setText("$0.0");
                        }
                    }, throwable -> Log.d(TAG, "MachineInfo 2: ERROR")));
    

    我注意到,如果是一个干净的答案,但它是有效的。

  • 申嘉慕
    2023-03-14

    你说失败是什么意思?数据库是否没有更新,或者您是否遇到了一些异常?

    无论如何,我看到的主要问题是,您没有订阅可完成的对象-没有这一点,它们将无法执行。

    So更改:

    machineViewModel.updateByID(id, total_amount);
    

    到例如:

    machineViewModel.updateByID(id, total_amount).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe();
    

    而且它会起作用(当然,您可能想向subscribe方法添加特定的订阅者)。

     类似资料:
    • 我正在尝试开发我的第一个RxJava例子 我有一个带有文本框和三个按钮的主要活动。第一个按钮初始化单独类中的整数。第二个按钮订阅一个可观察量,该可观察量假定正在观察整数。第三个按钮将整数的值减小 1。 这是我的密码 和班级 当我尝试使用 订阅时,它只是给了我 的值(即 6),然后它给了我完成! 然后我尝试使用,认为我需要使用,只是而不是,但后来我得到了一个返回的空的,然后再次完成! 有人能帮助我从

    • 在android 6.0.1 Samsung s6 Edge+上的测试 当device screen脱机并从debug中拔出时,可观察到的只是停止发射项目。如果设备打开,则开始发射对象。另一个问题是,在停止接收项目之前,我会按照相同项目的顺序随机地得到2/3个重复调用 ____________________________edit_________________________________

    • 我有两个可观察到的。它们都是可观察的类型 一种是冷的,称为初始值可观察(initialValueObservable),它通过可观察(Observable)从项目列表中发出。from()。 另一个是名为“valueUpdateObservable”的热门主题,它是一个发布主题,在出现新项目时通知订阅者。 在客户端中,我想同时订阅这两个,因此我从和发布的更新中获取初始值。我最初的方法是合并它们,但我

    • 问题内容: 给定汽车清单(),我可以这样做: 有没有办法我可以从一个到一个序列? 像没有参数的东西 问题答案: 您可以这样映射到: 请注意,flatMapping可能不会保留源可观察的顺序。如果订单对您很重要,请使用。

    • 我做了一个RxJava2实验,包括以下步骤: 从对象列表创建一个可观察对象。 使用EquiMapSing()将可观察对象发出的每个项目映射到SingleSource。在平图单()中,对可观察对象发出的每个项目执行异步操作。 收集ListB中的所有项目,使用Observable.toList() 结果:由于异步操作,ListB的项目顺序与ListA不同。 因此,flatMapSingle()的工作原