Helper Class 中的计算问题 - Return 在计算之前被命中
Calculation Problem in Helper Class - Return is hit before calculation
我目前的问题是我想创建一个 Helper class 来计算我的成本(存储在数据库中)以便更好地组织一切(因为我的两个活动中需要这个计算)。
现在计算代码(工作正常)只是写在两个 Activity 里面(这让一切变得很丑陋)。
所以:我创建了一个 "CostIntervalHelper"-Class.
我把我的代码放在那里并更改了一些东西,但我现在遇到了一个大问题。为了更好的解释,先放上计算方法的代码:
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。
在调试模式下,我检查了一下,我可以说:在 return 语句被命中后,计算完成(以正确的方式)。
现在我需要一个想法或示例,如何让我的代码首先(以正确的顺序)执行所有 subViewModel.getAll(Monthly/Biannually/Yearly)Costs().[...]
方法,然后点击 return 语句。
我知道这有点棘手,因为我正在使用 LiveData/ViewModel 但也许有人有想法!会很棒!先谢谢了!
public BigDecimal calculateMonthlyCosts(SubViewModel subViewModel...) {
如果您使用的是 LiveData,那么您的计算不应以同步函数的形式立即执行。
您不想 return BigDecimal,您想要创建一个基于其他 LiveData 之间的链的 LiveData,当其中一个 LiveData 发生变化时将更新 BigDecimal。
为此,您应该创建一个 MediatorLiveData,并且应该观察 LiveData 在其任何 "components" 发生变化时接收 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% 确定您的业务逻辑,可能需要遵循 or 概述的 "using tuples to combine multiple LiveData" 方式。
也可以参考this video.
我目前的问题是我想创建一个 Helper class 来计算我的成本(存储在数据库中)以便更好地组织一切(因为我的两个活动中需要这个计算)。
现在计算代码(工作正常)只是写在两个 Activity 里面(这让一切变得很丑陋)。
所以:我创建了一个 "CostIntervalHelper"-Class.
我把我的代码放在那里并更改了一些东西,但我现在遇到了一个大问题。为了更好的解释,先放上计算方法的代码:
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。 在调试模式下,我检查了一下,我可以说:在 return 语句被命中后,计算完成(以正确的方式)。
现在我需要一个想法或示例,如何让我的代码首先(以正确的顺序)执行所有 subViewModel.getAll(Monthly/Biannually/Yearly)Costs().[...]
方法,然后点击 return 语句。
我知道这有点棘手,因为我正在使用 LiveData/ViewModel 但也许有人有想法!会很棒!先谢谢了!
public BigDecimal calculateMonthlyCosts(SubViewModel subViewModel...) {
如果您使用的是 LiveData,那么您的计算不应以同步函数的形式立即执行。
您不想 return BigDecimal,您想要创建一个基于其他 LiveData 之间的链的 LiveData,当其中一个 LiveData 发生变化时将更新 BigDecimal。
为此,您应该创建一个 MediatorLiveData,并且应该观察 LiveData 在其任何 "components" 发生变化时接收 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% 确定您的业务逻辑,可能需要遵循
也可以参考this video.