当前位置: 首页 > 知识库问答 >
问题:

Android live data-配置更改后始终触发观察

全昊焜
2023-03-14

我目前正在重构代码,将ViewModel与android提供的LiveData结合起来。拱门图书馆。我有一个简单的活动,它向服务器发送更改密码的请求,并根据HTTP响应代码进行操作。

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

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

ChangePasswordViewModel

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响应代码的值还没有更新,那么如果实时数据没有更改,为什么。观察()会触发?

共有2个答案

伯晨
2023-03-14

除了上面的答案,了解使用ViewModel的场景也很重要

后源
2023-03-14

正如您在文档中看到的,这是一种预期行为:

观察者(生命周期所有者所有者,观察者观察者)将给定观察者添加到给定所有者生命周期内的观察者列表中。事件在主线程上分派。如果LiveData已经有数据集,它将被传递给观察者。

如果你想观察视图状态的变化,那么你应该创建并观察视图状态,而不是网络请求,谷歌已经为类似的情况提供了一个例子。

 类似资料:
  • 问题内容: 我正在尝试使用jQuery和JSON执行一些基本操作。目前,jQuery在从我的游戏框架应用程序接受JSON响应方面遇到困难。下面是仍然会产生错误的代码的简化版本。 错误回调总是被触发。它显示 错误…未调用parsererror jQuery15001997238997904205_1298484897373 通过Firebug检查返回的JSON不会显示任何错误,并且各种JSON li

  • 问题内容: 输出: 一些数据 完成X 1 一些数据 完成X 2 是我的使用错误还是..? 问题答案: 该API: 是不稳定 关于重复的通知,他已经知道“行为”。具体来说,Windows案例是Windows设计的结果,其中单个文件修改可以是对Windows API的多次调用

  • 问题内容: 由于声誉的限制,这是对先前问题的回答的后续问题。 但是想象一下一个有变化的列的大桌子。您必须比较每列,如果数据库发生更改,则必须调整触发器。而且比较硬编码的每一行都没有“感觉”好:) 是的,但这就是进行的方式。 附带说明一下,在更新之前先检查一下也是一种好习惯: 在您的示例中,这将使其更新(从而覆盖)两行而不是三行。 我想知道在处理NULL值时是否有更有效的方法来测试每个字段的更改。

  • 问题内容: 我有一个绑定到我的EventTracker bean的JTable,本质上是一个列表的包装,我将仅将其用作附加/清除(即,简单的日志)。问题是,当我将条目添加到列表中并尝试触发事件时,我看不到任何更改。我正在使用NetBeans IDE。 EventTracker bean被添加到视图中并实例化为eventTracker1。从那里,我右键单击表格,然后选择“表格内容…”。表模型已绑定到

  • 问题内容: 有一个在我的可调整大小的标题列的应用程序。通常,当我将光标移到表标题上方以调整大小时,光标图标会更改为调整大小的箭头,例如<->。 但是在以下情况下情况有所不同。 在同一按钮操作中,在执行操作期间,我将光标设置为忙碌图标,并在完成操作后使用方法将其更改为默认光标。 有时,如果将光标移到调整大小的表标题上,则在执行按钮操作后,光标图标不会更改为调整大小箭头,光标也不会更改。 可以将其视为

  • 小心使用“set”而不是其他内置方法,因为它不会在更改值后触发事件,正如这里的评论中指出的:如何在水豚中使用fill_in与查找(如果可能) 例如。 <代码>查找(:css,“输入[id$='捐赠\u质押\u数百']”)。设置(“10”) 我正在使用ruby、capybara和site prism。据我所知,site prism的使用方法是获取capybara节点元素,然后对其调用方法,例如单击