【问题标题】:Live Data is getting called multiple times?实时数据被多次调用?
【发布时间】:2018-04-10 03:03:37
【问题描述】:

我在我的应用程序中使用Android Architecture Components。在我的登录活动中,登录失败时我会显示一个对话框!

由于实时数据,对话框已显示 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 之后。它没有被观察到。你能告诉我代码有什么问题吗?

更新的视图模型

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;
    }
}

【问题讨论】:

标签: android android-livedata


【解决方案1】:

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

总之:

  • 创建一个名为 CurrentAuthenticatedSession 之类的类,例如一个用户名字段,并以 null 开头
  • 进行身份验证调用时,验证查找用户信息
  • 如果是当前更新 CurrentAuthenticatedSession 的 LiveData 实例
  • 让“currentlyLoggedInUser”字段监听此对象的更新
  • 将该控件的文本设置为字段用户名的值

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

【讨论】:

    【解决方案2】:

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

    原回答here

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

    场景是什么? 该应用程序有一个色板。当用户选择一种颜色时,我必须调用 API 来获取该颜色的产品图像。进行 API 调用并在 onColorChanged() 中观察 livedata 也是如此。当用户选择一种新颜色时,onColorChanged() 会再次被调用,从而再次观察 livedata 的变化。

    【讨论】:

    • 你在onCreate时说的都是在说activity吗?在片段中做什么?
    • 对于 Fragment,在 onViewCreated() 方法中观察 livedata。 @MaximeClaude
    • 我在 onViewCreated 中做到了,但我仍然遇到同样的问题。我必须使用我在这里找到的 observeOnce stackoverflow.com/a/54648758/3808178
    猜你喜欢
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    相关资源
    最近更新 更多