实时数据被多次调用?

时间:2017-10-28 18:34:40

标签: android android-livedata

我在我的应用中使用Android Architecture Components。在我的登录Activty中,我在登录失败时显示对话框!

由于实时数据,对话框已显示超过3次。我添加了一些日志&发现多次调用livedata

如何解决此问题?

活性

mViewModel.authenticate(token, binding.inputPassword.getText().toString()).observe(LoginActivity.this, apiResponse -> {
    progress.dismiss();
    if (apiResponse != null) {
        if (apiResponse.getError() != null) {
            Log.e("Login", "Network Failure");
        } else {
            if (apiResponse.getAuthuser().getStatus().equals("VALID")) {
                PrefUtils.saveUserToPrefs(LoginActivity.this, apiResponse.getAuthuser());
                finish();
            } else if (apiResponse.getAuthuser().getStatus().equals("INVALID")) {
                Log.e("LOGIN Issue ", "Showing Dialog" + apiResponse.getAuthuser().getStatus());
                loginFailure();
            }
        } 
    }
});

视图模型

class LoginActivityViewModel extends ViewModel {

    private final FarmerRepository farmerRepository;
    private MediatorLiveData<ApiResponse> mApiResponse;

    LoginActivityViewModel(FarmerRepository repository) {
        mApiResponse = new MediatorLiveData<>();
        farmerRepository = repository;
    }

    MediatorLiveData<ApiResponse> authenticate(String encryptedMobile, String pwd) {
        mApiResponse.addSource(
                farmerRepository.authenticate(encryptedMobile, pwd),
                apiResponse -> mApiResponse.setValue(apiResponse)
        );
        return mApiResponse;
    }
}

logcat的

11-01 00:13:31.265 24386-24386 E/LOGIN Issue: Showing DialogINVALID

11-01 00:13:31.312 24386-24386 E/LOGIN Issue: Showing DialogINVALID
11-01 00:13:37.034 24386-24386 E/LOGIN Issue: Showing DialogINVALID

11-01 00:13:38.196 24386-24386 E/LOGIN Issue: Showing DialogINVALID
11-01 00:13:38.234 24386-24386 E/LOGIN Issue: Showing DialogINVALID
11-01 00:13:38.273 24386-24386 E/LOGIN Issue: Showing DialogINVALID

更新

使用SingleLiveEvent后。它没有被观察到。你能告诉我代码有什么问题吗?

更新了ViewModel

class LoginActivityViewModel extends ViewModel {

    private final FarmerRepository farmerRepository;
    private MediatorLiveData<ApiResponse> mApiResponse;
private SingleLiveEvent<ApiResponse> mMsgUpdate;

    LoginActivityViewModel(FarmerRepository repository) {
        mApiResponse = new MediatorLiveData<>();
        farmerRepository = repository;
    mMsgUpdate = new SingleLiveEvent<>();
    }

    SingleLiveEvent<ApiResponse> authenticate(String encryptedMobile, String pwd) {
        mApiResponse.addSource(
                farmerRepository.authenticate(encryptedMobile, pwd),
                apiResponse -> mMsgUpdate.setValue(apiResponse)
        );
        return mMsgUpdate;
    }
}

2 个答案:

答案 0 :(得分:8)

ViewModel的作用是表示视图的当前状态。 LiveData增加了观察状态变化的能力。您正在将LiveData对象视为在进行身份验证调用时返回响应的方法。相反,您的身份验证方法应该简单地将凭据作为参数,决定是否记录此人,如果您这样做,更新LiveData ViewModel以反映该人员已登录,那么观察者将得到这个并且很可能会解雇此视图显示您要显示的身份验证状态的其他任何部分(例如LoggedInUsername)。

总结如下:

  • 创建一个名为CurrentAuthenticatedSession的类,例如用户名字段,并以
  • 开头为空
  • 进行身份验证调用时,请验证查找用户信息
  • 如果它当前更新了CurrentAuthenticatedSession的LiveData实例
  • 让'currentlyLoggedInUser'字段正在侦听此对象的更新
  • 将该控件的文本设置为字段用户名
  • 的值

这是一种方式。由于登录屏幕是暂时的,因此状态更新的观察者可能被视为多余的。但这就是ViewModel / LiveData机制的工作原理。

答案 1 :(得分:2)

我的答案不是此问题描述的解决方案,而是问题标题的解决方案。只是标题。

最初回答here

如果您的LiveData观察者<*>被多次调用,则意味着您多次调用livedata.observe(...)。在我做livedata时,这发生在我身上.observe(...)在一个方法中,并在用户执行任何操作时调用此方法,从而再次观察liveData。为了解决这个问题,我将livedata.observe(...)移到了onCreate()生命周期方法中。

情况如何? 该应用程序有一个色板。当用户选择一种颜色时,我必须进行API调用以获取该颜色的产品图片。因此,进行API调用并观察onColorChanged()中的实时数据。当用户选择新颜色时,onColorChanged()将再次被调用,从而再次观察实时数据的变化。