java - Helper 类中的计算问题 - 在计算之前返回值

标签 java android android-livedata android-jetpack

我当前的问题是我想创建一个 Helper 类来计算我的成本(存储在数据库中),以便更好地组织一切(因为我需要在我的两个 Activity 中进行此计算)。

现在计算代码(工作正常)只是写在两个 Activity 内部(这使得一切变得相当难看)。

所以:我创建了一个“CostIntervalHelper”类。

我把我的代码放在那里并改变了一些东西,但我现在遇到了一个大问题。为了更好的解释,先看一下计算方法的代码:

 public BigDecimal calculateMonthlyCosts(SubViewModel subViewModel, Context context){
    //set this two times just for debugging reasons to see if the calculation actually works
    cMonthly = new BigDecimal(0);

    subViewModel.getAllMonthlyCosts().observe((LifecycleOwner) context, new Observer<BigDecimal>() {
        @Override
        public void onChanged(@Nullable BigDecimal bigDecimal) {
            cMonthly = new BigDecimal(0);
            if (bigDecimal != null) {
                cMonthly = cMonthly.add(bigDecimal);
            }
        }
    });

    subViewModel.getAllBiannuallyCosts().observe((LifecycleOwner) context, new Observer<BigDecimal>() {
        @Override
        public void onChanged(@Nullable BigDecimal bigDecimal) {
            cBiannually = new BigDecimal(0);
            if (bigDecimal != null) {
                cBiannually = cBiannually.add(bigDecimal.divide(new BigDecimal(6), 2));
            }
        }
    });

    subViewModel.getAllYearlyCosts().observe((LifecycleOwner) context, new Observer<BigDecimal>() {
        @Override
        public void onChanged(@Nullable BigDecimal bigDecimal) {
            cYearly = new BigDecimal(0);
            if (bigDecimal != null) {
                cYearly = cYearly.add(bigDecimal.divide(new BigDecimal(12), 2));
                cMonthly = cMonthly.add(cBiannually).add(cYearly);
            }
        }
    });

    //return is hit before the calculation so it only returns "0"
    return cMonthly;
}

现在我们来解决问题(已经在代码中添加了一些注释):

每当我调用该方法时,都会首先调用 return cMonthly。 在 Debug模式下,我检查了一下,我可以说:在返回语句被命中后,计算完成(以正确的方式)。

现在我需要一个想法或示例,如何使我的代码首先(以正确的顺序)执行所有 subViewModel.getAll(Monthly/Biannually/Yearly)Costs().[...] 方法并 AFTERWARDS 命中 return 语句。

我知道这有点棘手,因为我正在使用 LiveData/ViewModel,但也许有人有一个想法!会很棒的!先谢谢了!

最佳答案

public BigDecimal calculateMonthlyCosts(SubViewModel subViewModel...) {

如果您使用LiveData,那么您的计算不应以同步函数的形式立即进行。

您不想返回 BigDecimal,而是希望创建一个基于其他 LiveData 之间的链的 LiveData,当其中一个 LiveData 发生更改时,该链将更新 BigDecimal。

为此,您应该创建一个 MediatorLiveData,并且应该观察 LiveData 在其任何“组件”发生更改时接收 BigDecimal 的最新值。

public LiveData<BigDecimal> calculateMonthlyCosts(SubViewModel subViewModel) {
    MediatorLiveData<BigDecimal> mediator = new MediatorLiveData<>() {
        private BigDecimal cMonthly = new BigDecimal(0);
        private BigDecimal cBiannually = new BigDecimal(0);
        private BigDecimal cYearly = new BigDecimal(0);

        {
            addSource(subViewModel.getAllMonthlyCosts(), new Observer<BigDecimal>() {
                @Override
                public void onChanged(@Nullable BigDecimal bigDecimal) {
                    if (bigDecimal != null) {
                        cMonthly = cMonthly.add(bigDecimal);
                        setValue(cMonthly);
                    }
                }
            });

            addSource(subViewModel.getAllBiannuallyCosts(), new Observer<BigDecimal>() {
                @Override
                public void onChanged(@Nullable BigDecimal bigDecimal) {
                    if (bigDecimal != null) {
                        cBiannually = cBiannually.add(bigDecimal.divide(new BigDecimal(6), 2));
                        setValue(cMonthly); // TODO: ???
                    }
                }
            });

            addSource(subViewModel.getAllYearlyCosts(), new Observer<BigDecimal>() {
                @Override
                public void onChanged(@Nullable BigDecimal bigDecimal) {
                    if (bigDecimal != null) {
                        cYearly = cYearly.add(bigDecimal.divide(new BigDecimal(12), 2));
                        cMonthly = cMonthly.add(cBiannually).add(cYearly);
                        setValue(cMonthly);
                    }
                }
            });
         }
    };

    return mediator;
}

请注意,我不能 100% 确定您的业务逻辑,可能需要遵循 here 中概述的“使用元组组合多个 LiveData”的方式或here .

您也可以引用this video .

关于java - Helper 类中的计算问题 - 在计算之前返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55442175/

相关文章:

java - spring boot Jar to war【同学-1.3.3.jar(系统找不到指定路径)】

java - 我的代码有什么问题(初学者)(Java)

Java Scanner 不等待用户输入

java - 错误 :(134, 0) 无法获取 org.gradle.api.internal.FactoryNamedDomainObjectContainer 类型的 SigningConfig 容器的未知属性 'release'。

android - 如何将两个可变实时数据的结果合二为一

java - SFTP 和 Camel 。无法将目录更改为。私钥无效

Android ListView 状态列表不显示默认项目背景

android - 将 Google Play 服务库导入移动广告示例

android - ViewModel 中的实例成员 LiveData 变量?

android - 如何结合 livedata 和 kotlin flow