Я новичок в разработке 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 был нулевым
в обоих случаях функция изменения наблюдателя не посещалась.
Кто-нибудь знает, что я делаю неправильно?
спасибо, Ронен!