在Observable结果RxJava

时间:2018-04-10 19:30:45

标签: android rx-java rx-java2 android-room

你好

应用:我有一个非常基本的应用,其中有一些计算机 (名称,ID,总计收入)和一些收入 (id,money,note,machines_id)。在第一个屏幕上,我允许用户从FAB添加一台机器,然后我在RecyclerView中显示它。当用户点击任何机器时,我将它们导航到第二个屏幕,在那里用户可以看到机器的名称,总收入和带有相应收入的RecyclerView;有一个FAB,可以让他们为该机器增加收入并刷新RecyclerView。

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

我已设法使用会议室 .allowMainThreadQueries()和传统方法。

MachineViewModel

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

MachineDAO

@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 World 时,如下面的方法我没有更新但没有崩溃,“方法的返回值从未使用过”

MachineViewModel

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

MachineDAO

@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:失败

MachineViewModel

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

MachineDAO

@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 个答案:

答案 0 :(得分:1)

失败是什么意思?数据库没有得到更新,还是有一些例外?

无论如何,我看到的主要问题是你没有订阅你的Completable对象 - 如果没有这个,它们就不会被执行。

所以改变:

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

例如:

subscribe

它将起作用(当然,您可能希望将特定的订阅者添加到id="chkbox"方法)。

答案 1 :(得分:0)

好的,所以感谢迈克尔我设法找到问题的漏洞。

显然,你可以在 Disposables 添加一次性用品

  • 您需要初始化 Observable 并添加 .observeOn(etc).subscribeOn(etc).subscribe(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")));
    

我要注意确定是否是一个干净的答案,但它有效。