使用 room 和 mvvm 添加记录并通知 activity 的正确方法
proper way to add a record and notify activity using room and mvvm
我正在学习android mvvm 结构,但我在实现它时有疑问。我正在使用房间在数据库中插入一个用户对象。但是,我不知道如何在插入成功后通知activity。
我已经尝试实现了。但是,它没有用。让我展示一下我的代码。
RegisterActivity
public class RegisterActivity extends AppCompatActivity {
ActivityRegisterBinding activityRegisterBinding;
RegisterViewModel registerViewModel;
private final CompositeDisposable mDisposable = new CompositeDisposable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDataBinding();
onUserRegistered();
}
private void initDataBinding() {
activityRegisterBinding = DataBindingUtil.setContentView(this, R.layout.activity_register);
RegisterViewModelFactory registerViewModelFactory = Injection.provideRegisterViewModelFactory(this);
registerViewModel = ViewModelProviders.of(this,registerViewModelFactory).get(RegisterViewModel.class);
activityRegisterBinding.setRegisterViewModel(registerViewModel);
}
private void onUserRegistered() {
findViewById(R.id.register_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDisposable.add(registerViewModel.onClickedSignUp()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action() {
@Override
public void run() throws Exception {
Log.e("Success!!!","added a record");
Toast.makeText(RegisterActivity.this,"success",
Toast.LENGTH_SHORT).show();
onBackPressed();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e("Unable to add a record", throwable.toString());
throwable.printStackTrace();
}
}));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mDisposable.dispose();
}
}
RegisterViewModel
public class RegisterViewModel extends ViewModel {
public ObservableField<String> name;
public ObservableField<String> password;
private UserDataSource userDataSource;
RegisterViewModel(UserDataSource userDataSource){
name=new ObservableField<>("");
password=new ObservableField<>("");
this.userDataSource=userDataSource;
}
public TextWatcher nameWatcher=new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(!name.get().equals(s.toString())){
name.set(s.toString());
}
}
};
public TextWatcher passwordWatcher=new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(!password.get().equals(s.toString())){
password.set(s.toString());
}
}
};
public Completable onClickedSignUp() {
isLoading.setValue(true);
if (name != null)
Log.e("name", name.get());
if (password != null)
Log.e("pass", String.valueOf(password.get()));
return Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
Log.e("final name",name.get());
User user=new User(0,name.get(),0,0);
userDataSource.insertOrUpdateUser(user);
}
});
}
}
我在从视图模型打印的日志中获得了正确的名称和密码值,但记录没有添加到按钮上的单击事件中,它也没有通知 activity 关于成功或失败。遇到这种情况怎么办?
请指导我,因为我是 mvvm 的新手并且正在学习它。
Data Access Object接口中insert方法的return无效。插入数据时您不会收到回电。您可以在调用插入方法后执行您想要执行的任务
此外,我建议您在 activity
的 onDestroy
方法中处理在 mDisposable 中添加的一次性用品
我正在学习android mvvm 结构,但我在实现它时有疑问。我正在使用房间在数据库中插入一个用户对象。但是,我不知道如何在插入成功后通知activity。
我已经尝试实现了。但是,它没有用。让我展示一下我的代码。
RegisterActivity
public class RegisterActivity extends AppCompatActivity {
ActivityRegisterBinding activityRegisterBinding;
RegisterViewModel registerViewModel;
private final CompositeDisposable mDisposable = new CompositeDisposable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDataBinding();
onUserRegistered();
}
private void initDataBinding() {
activityRegisterBinding = DataBindingUtil.setContentView(this, R.layout.activity_register);
RegisterViewModelFactory registerViewModelFactory = Injection.provideRegisterViewModelFactory(this);
registerViewModel = ViewModelProviders.of(this,registerViewModelFactory).get(RegisterViewModel.class);
activityRegisterBinding.setRegisterViewModel(registerViewModel);
}
private void onUserRegistered() {
findViewById(R.id.register_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDisposable.add(registerViewModel.onClickedSignUp()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action() {
@Override
public void run() throws Exception {
Log.e("Success!!!","added a record");
Toast.makeText(RegisterActivity.this,"success",
Toast.LENGTH_SHORT).show();
onBackPressed();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e("Unable to add a record", throwable.toString());
throwable.printStackTrace();
}
}));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mDisposable.dispose();
}
}
RegisterViewModel
public class RegisterViewModel extends ViewModel {
public ObservableField<String> name;
public ObservableField<String> password;
private UserDataSource userDataSource;
RegisterViewModel(UserDataSource userDataSource){
name=new ObservableField<>("");
password=new ObservableField<>("");
this.userDataSource=userDataSource;
}
public TextWatcher nameWatcher=new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(!name.get().equals(s.toString())){
name.set(s.toString());
}
}
};
public TextWatcher passwordWatcher=new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(!password.get().equals(s.toString())){
password.set(s.toString());
}
}
};
public Completable onClickedSignUp() {
isLoading.setValue(true);
if (name != null)
Log.e("name", name.get());
if (password != null)
Log.e("pass", String.valueOf(password.get()));
return Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
Log.e("final name",name.get());
User user=new User(0,name.get(),0,0);
userDataSource.insertOrUpdateUser(user);
}
});
}
}
我在从视图模型打印的日志中获得了正确的名称和密码值,但记录没有添加到按钮上的单击事件中,它也没有通知 activity 关于成功或失败。遇到这种情况怎么办?
请指导我,因为我是 mvvm 的新手并且正在学习它。
Data Access Object接口中insert方法的return无效。插入数据时您不会收到回电。您可以在调用插入方法后执行您想要执行的任务
此外,我建议您在 activity
的onDestroy
方法中处理在 mDisposable 中添加的一次性用品