【问题标题】:Android live data - observe always fires after config changeAndroid 实时数据 - 配置更改后观察总是触发
【发布时间】:2018-03-16 10:07:33
【问题描述】:

我目前正在重构我的代码以包含 ViewModel 和 android.arch 库提供的 LiveData。我有一个简单的活动,它将更改密码的请求发送到服务器并根据 HTTP 响应代码进行操作。

为此,我创建了为数据扩展 ViewModel 的类和一个用于调用服务器的存储库类。我的 ViewModel 类有一个 MutableLiveData 字段,我使用 .observe(...) 方法从我的活动中订阅该字段。问题是 .observe(...) 中的代码在配置更改(即屏幕旋转)后一直触发,我不知道为什么。

下面是相应的 ViewModel、Repository 和 Activity 类的代码:

更改密码视图模型

public class ChangePasswordViewModel extends ViewModel{

    private MutableLiveData<Integer> responseCode;
    private PasswordChangeRepository passwordChangeRepository;

    public ChangePasswordViewModel() {
        responseCode = new MutableLiveData<>();
        passwordChangeRepository = new PasswordChangeRepositoryImpl();
    }

    public MutableLiveData<Integer> responseCodeLiveData() {
        return responseCode;
    }

    public void sendChangePasswordRequest(String newPassword){
        passwordChangeRepository.changePassword(newPassword,     passChangeCallback());
    }

    // Callback that fires after server sends a response
    private Callback passChangeCallback(){
        ...
        responseCode.postValue(serverResponse)
        ...
}

密码更改存储库

public class PasswordChangeRepositoryImpl {

    public void changePassword(String newPassword, Callback<Void> callback){
        //Sending new password to server and processing response in callback
        ServerCalls.changePassword(newPassword, callback);
    }
}

活动

public class ChangePasswordActivity extends AppCompatActivity{
...
    private void init(){
        //Getting appropriate view model
        passwordViewModel = ViewModelProviders.of(this).get(ChangePasswordViewModel.class);

        // Starting to observe LiveData
        passwordViewModel.getResponseCode().observe(this, responseCode -> {
           Log.info("Server response is " + responseCode);
        });

        //Sending new password to server
        buttonPassChange.setOnClickListener(view ->
            passwordViewModel.sendChangePasswordRequest("newPass")
        );
    }
...
}

问题是我第一次使用 sendChangePasswordRequest(...) 向服务器发送请求后观察活动中的代码

passwordViewModel.getResponseCode().observe(this, responseCode -> {
           Log.info("Server response is " + responseCode);
        });

每次旋转屏幕后都会触发。为什么会这样?自上次服务器调用以来 MutableLiveData responseCode 的值尚未更新,那么如果实时数据没有更改,为什么 .observe() 会触发?

【问题讨论】:

    标签: android android-lifecycle android-livedata


    【解决方案1】:

    这是一种预期行为,正如您在 documents 中看到的那样:

    观察(LifecycleOwner 所有者, 观察者观察者)在给定所有者的生命周期内将给定观察者添加到观察者列表中。事件是 在主线程上调度。如果 LiveData 已经有数据集,它 将交付给观察者。

    如果你想观察视图状态的变化,那么你应该创建并观察视图状态而不是网络请求,谷歌已经为这种情况提供了example

    【讨论】:

      【解决方案2】:

      除了上面的回答之外,重要的是要了解使用 ViewModel 和 LiveData 观察者的场景,只观察一次,本文解释了它们并展示了一种轻松处理它的方法:Working with LiveData and Events

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-30
        相关资源
        最近更新 更多