android - 无法从 ViewModel 观察实时数据

标签 android mvvm retrofit

我在 MVVM 设计模式上实现了一个简单的手机号码登录。但是当从服务器返回响应时,不会调用 Onchanged 函数。

登录 View 模型

public class LoginViewModel extends ViewModel {

private LoginModel login;
private MutableLiveData<LoginResponse> loginresponse = new MutableLiveData<>();
private LoginRepository loginrepository;


public void init() {
    login = new LoginModel();
}


public LoginModel getLogin() {
    return login;
}


public void onLoginClick() {
   if(login.isPhonevalid()){
       HashMap<String,Object> loginObject = new HashMap<>();
       loginObject.put("phonenumber",login.getMobileNumber());
       loginObject.put("apimethod","beatme");
       loginresponse = LoginRepository.getInstance().login(loginObject);
      // loginClick.setValue(login);
      }
}


@BindingAdapter("error")
public static void setError(EditText editText, String errormessage) {
    editText.setError(errormessage);

}


public MutableLiveData<LoginResponse> getLoginresponse() {
    return loginresponse;
}


public String getMobileNo(){
    return login.getMobileNumber();
}
}

登录存储库

public class LoginRepository {


private static LoginRepository loginRepository;
private Api api;

public static LoginRepository getInstance() {
    if (loginRepository == null) {
        loginRepository = new LoginRepository();
    }
    return loginRepository;
}


public LoginRepository() {
    api = RetrofitService.createService(Api.class);
}


public MutableLiveData<LoginResponse> login(HashMap<String, Object> body) {

    final MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
    api.login(body).enqueue(new Callback<LoginResponse>() {
        @Override
        public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
            if (response.isSuccessful()) {
                loginResponse.setValue(response.body());
            }
        }

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

    return loginResponse;
}

}

登录 Activity

public class LoginActivity extends AppCompatActivity {

private LoginViewModel viewModel;
ActivityLoginBinding activityLoginBinding;




boolean doubleBackToExitPressedOnce = false;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_login);
    getSupportActionBar().hide();
    activityLoginBinding  = DataBindingUtil.setContentView(LoginActivity.this, R.layout.activity_login);

    viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
    if (savedInstanceState == null) {
        viewModel.init();
    }
    activityLoginBinding.setLoginViewModel(viewModel);
    setuploginclick();

}

public void setuploginclick() {
    viewModel.getLoginresponse().observe(this, new Observer<LoginResponse>() {
        @Override
        public void onChanged(LoginResponse loginResponse) {

            Toast.makeText(LoginActivity.this,viewModel.getMobileNo(),Toast.LENGTH_SHORT).show();
            Intent i = new Intent(LoginActivity.this, OTPVerify.class);
            i.putExtra("mobileno",viewModel.getMobileNo());
            startActivity(i);
        }
    });

}
}

从日志中可以看出数据发布成功,响应也很完美。但是为实时数据“loginresponse”赋值并不调用 observable。

最佳答案

ViewModel 中删除 loginResponse 并在 Repository 中创建它,然后将存储库 loginResponse 传递给您的 Activity 。检查下面

public class LoginRepository {
    public MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
    ...

    //getter
    public MutableLiveData<LoginResponse> getLoginResponse() {
        return loginResponse
    }
}

然后在 ViewModel 中:

public class LoginViewModel extends ViewModel {
    ...

    public MutableLiveData<LoginResponse> getLoginResponse() {
        return LoginRepository.getInstance().getLoginResponse()
    }

    ...

    public void onLoginClick() {
        if(login.isPhonevalid()){
            HashMap<String,Object> loginObject = new HashMap<>();
            loginObject.put("phonenumber",login.getMobileNumber());
            loginObject.put("apimethod","beatme");
            LoginRepository.getInstance().login(loginObject);
            // loginClick.setValue(login);
        }
    }

    ...
}

像下面这样更改您在 Repository 中的登录功能:

public void login(HashMap<String, Object> body) {

    api.login(body).enqueue(new Callback<LoginResponse>() {
        @Override
        public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
            if (response.isSuccessful()) {
                loginResponse.postValue(response.body());
            }
        }

        @Override
        public void onFailure(Call<LoginResponse> call, Throwable t) {
            loginResponse.postValue(null);
        }
}

关于android - 无法从 ViewModel 观察实时数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58968611/

相关文章:

android - 将变量从服务传递到广播接收器

java - 当使用回收器 View 和 View 模型获取数据时,映射器函数返回空值

android - 改造编码特殊字符

java - 如何将两个改造请求中的数据传递到单个 recyclerview 适配器

java - 推送完后如何获取 child 的数据?

java - Android - 生成随机数时崩溃

android - ListView - 每个项目都有一个 ID?

java - ZK MVVM 验证消息自动绑定(bind)?

WPF 合并项目源列表

mvvm - ViewModel 如何获得有关数据项属性更改的通知?