Почему при моей активности наблюдаемый объект не меняется?

Я новичок в разработке Android, и я пытаюсь понять Live Data с архитектурой MVVM. Я пытаюсь заставить основное действие распознавать, когда происходит изменение объекта, принадлежащего модели представления деятельности.

Я создал простую операцию входа в систему, которая берет текст из полей имени пользователя и пароля и передает их функции входа в модель представления, затем функция отправляет данные в репозиторий пользователей, а затем делает запрос POST к серверу Spring, который работает на моем компьютере. Функция входа в репозиторий возвращает объект MutableLiveData с зарегистрированным именем пользователя, если имя пользователя и пароль верны, и null в качестве значения в противном случае. Репозиторий работает нормально (данные, возвращаемые с сервера, верны). Модель представления имеет поле типа MutableLiveData, и его необходимо обновить после вызова функции входа в систему. В действии есть наблюдатель, который должен получать уведомление, когда в поле loggedInUser (типа MutableLiveData) происходит изменение, и даже если есть изменение, функция onChange наблюдателя никогда не активируется.

Есть некоторый код, который, я надеюсь, поможет мне лучше объяснить.

Основная деятельность:

public class MainActivity extends AppCompatActivity {
        public EditText usernameTxt;
        public EditText passwordTxt;
        public Button loginBtn;
        public String loggedInuUser;
        LoginViewModel loginViewModel;


    @Override
    protected void onCreate(Bundle savedInstanceState) {



        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        usernameTxt = findViewById(R.id.usernameTxt);
        passwordTxt   = findViewById(R.id.passwordTxt);
        loginBtn   = findViewById(R.id.loginBtn);

        loginViewModel = ViewModelProviders.of(this ).get(LoginViewModel.class);
        loginViewModel.init();
        try {
            loginViewModel.getLoggedInUser().observe(this, new Observer<String>() {
                        @Override
                        public void onChanged(@Nullable String s) {
                            Toast toast=  Toast.makeText(MainActivity.this,"changed" , Toast.LENGTH_LONG );
                            toast.show();
                        }
                    }
            );
        }catch (Exception e){
            System.out.println("==========================================================");
            System.out.println( e.getMessage());
            System.out.println("==========================================================");
        }

    }


    protected void onLogInCliked(View v ){

//        Toast toast=  Toast.makeText(getApplicationContext(),loggedInuUser, Toast.LENGTH_LONG );
//        toast.show();
        loginViewModel.login(usernameTxt.getText().toString(),passwordTxt.getText().toString());
//        Toast toast2=  Toast.makeText(getApplicationContext(),loggedInuUser, Toast.LENGTH_LONG );
//        toast2.show();


    }
}

модель просмотра:

public class LoginViewModel extends ViewModel {


    private UsersRepository usersRepository;
    private MutableLiveData<String> loggedInUser;

    public void init(){
        if(loggedInUser!= null){
            return;
        }

        usersRepository = UsersRepository.getInstance();
        loggedInUser=new MutableLiveData<>();
    }


    public MutableLiveData<String> getLoggedInUser(){
        return loggedInUser;
    }

    public void login(String userName , String hashedPassword) {

        loggedInUser = usersRepository.login(userName, hashedPassword);
    }
}

репозиторий:

public class UsersRepository {

private static UsersRepository usersRepository;

public static UsersRepository getInstance(){
    if (usersRepository == null){
        usersRepository = new UsersRepository();
    }
    return usersRepository;
}

private UsersRepositoryApi usersRepositoryApi;

public UsersRepository(){
    usersRepositoryApi = RetrofitService.cteateService(UsersRepositoryApi.class);
}


public MutableLiveData<String> login(String username , String hashedPassword){
   final MutableLiveData<String> loggedInUser = new MutableLiveData<>();
    User user = new User(username,hashedPassword);

    usersRepositoryApi.login(user).enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if (response.isSuccessful()) {
                loggedInUser.setValue(response.body());
            }
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            loggedInUser.setValue(null);
        }
    });

    return loggedInUser;
}

}

В mainActivity я устанавливаю наблюдателя и ожидаю, что приложение покажет мое сообщение Toast, но ничего не происходит.

Я попытался посмотреть, что происходит в модели представления, и это немного странно, поэтому я напечатал что-то вроде этого:

    public void login(String userName , String hashedPassword) {

    System.out.println("222======================================");
    System.out.println("==========================================");
    System.out.println("==========================================");
    System.out.println(loggedInUser.getValue());
    System.out.println("==========================================");
    System.out.println("==========================================");
    System.out.println("==========================================");
    loggedInUser = usersRepository.login(userName, hashedPassword);

    System.out.println("333======================================");
    System.out.println("==========================================");
    System.out.println("==========================================");
    System.out.println(loggedInUser.getValue());
    System.out.println("==========================================");
    System.out.println("==========================================");
    System.out.println("==========================================");

}

в первый раз, когда я запустил функцию входа в систему, выходные данные 222 и 333 были нулевыми, но во второй раз, когда я запустил функцию входа, выход 222 был loggedInUser, а выход 333 был нулевым

в обоих случаях функция изменения наблюдателя не посещалась.

Кто-нибудь знает, что я делаю неправильно?

спасибо, Ронен!


person Ronen    schedule 25.07.2019    source источник


Ответы (3)


здесь ваша проблема с кодом репозитория внутри репозитория, вы создаете новый объект изменяемых живых данных и наблюдаете за другим.

Interface Callback{
    onSuccess(String response)
    onError(String error)
}

public void login(String username , String hashedPassword,Callback callback){
    final MutableLiveData<String> loggedInUser = new MutableLiveData<>();
    User user = new User(username,hashedPassword);

    usersRepositoryApi.login(user).enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if (response.isSuccessful()) {
                callback.onSuccess(response.body());
            }
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            callback.onError(null);
        }
    });
}
//login method of your viewmodel 
public void login(String userName , String hashedPassword) {
     usersRepository.login(userName, hashedPassword,new Callback(){
          void onSuccess(String responsebody){
               loggedInUser.setValue(responsebody);
          }

          void onError(String error){
               loggedInUser.setValue(responsebody);
          }
     });
}
person Neha Rathore    schedule 26.07.2019

В вашем репозитории попробуйте изменить эту часть:

loggedInUser.setValue(response.body());

в функцию postValue. как это:

loggedInUser.postValue(response.body());
person LionErez    schedule 25.07.2019
comment
спасибо за ответ, но, к сожалению, это не решило проблему - person Ronen; 26.07.2019

Решение OP.

Как предположила Неха Ратор, это решение, которое работает для меня:

в представлении Модель:

public void login(String userName , String hashedPassword) {
    usersRepository.login(userName, hashedPassword, new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            loggedInUser.setValue(response.body());
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            loggedInUser.setValue(null);
        }
    });
}

и в Репозитории:

public void login(String username, String hashedPassword,@Nullable final Callback<String> callback){
    final MutableLiveData<String> loggedInUser = new MutableLiveData<>();
    User user = new User(username,hashedPassword);

    usersRepositoryApi.login(user).enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            if (response.isSuccessful()) {
                callback.onResponse(call,response);
            }
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            callback.onFailure(call,t);
        }
    });
}
person Community    schedule 12.12.2019