web-dev-qa-db-ja.com

Androidライブデータ-設定変更後は常に発火します

現在、コードをリファクタリングして、Android.Archライブラリによって提供されるLiveDataにViewModelを含めています。パスワード変更のリクエストをサーバーに送信し、HTTP応答コードに従って動作する単純なアクティビティがあります。

そのために、データのViewModelを拡張するクラスと、サーバーを呼び出すリポジトリクラスを作成しました。私のViewModelクラスには、.observe(...)メソッドを使用してアクティビティからサブスクライブする1つのMutableLiveDataフィールドがあります。問題は、.observe(...)内のコードが構成の変更(つまり、画面の回転)の後で常に起動することであり、その理由がわかりません。

以下は、ViewModel、Repository、Activityクラスのコードです。

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)
        ...
}

PasswordChangeRepository

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()が起動するのはなぜですか?

10

documents で確認できるように、これは意図された動作です。

observe(LifecycleOwner所有者、オブザーバーオブザーバー)指定された所有者のライフスパン内のオブザーバーリストに指定されたオブザーバーを追加します。イベントはメインスレッドでディスパッチされます。 LiveDataにすでにデータセットがある場合は、オブザーバーに配信されます。

ビューステートの変化を観察したい場合は、ネットワークリクエストではなくビューステートを作成して観察する必要があります。このような場合のために、Googleはすでに example を提供しています。

6
Keivan Esbati

上記の回答に加えて、ViewModelおよびLiveDataオブザーバーを使用するシナリオを理解し、1回だけ監視することが重要です。この記事では、それらについて説明し、簡単に対処する方法を示します。 LiveDataおよびイベントの操作 =

2
Carlos Daniel