在 MVVM 架构中从存储库插入数据后无法切换到 MainActivity
Unable to switch to MainActivity after data insertion from repository in MVVM architecture
我正在为应用程序实施 MVVM 架构模式 development.I 有两个活动 MainActivity 和 AddUser activity.In MainActivity 我正在显示所有笔记的列表,在 AddUser activity 我在 room[=43= 中插入用户] database.I 正在存储库中执行所有插入和获取注释操作 class.I 正在使用 RxJava Completable 运算符在数据库中插入注释。
我想要的:插入后它应该重定向到 MainActivity。
问题: 使用 Intent 时无法在 onComplete() 方法中添加 Intent,它显示错误。
错误
Process: com.app.notesreactive, PID: 3970
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.
下面是我的代码:
UserDao.java
@Dao
public interface UserDao {
@Insert
void insert(User user);
@Query("SELECT * FROM Users ORDER BY id DESC")
LiveData<List<User>> getAllUsers();
}
UserRepository.java
public class UserRepository {
private UserDb userDb;
private UserDao userDao;
private LiveData<List<User>> allUsers;
private Context ctx;
public UserRepository(Application application) {
userDb = UserDb.getInstance(application);
userDao = userDb.userDao();
allUsers = userDao.getAllUsers();
ctx = application.getApplicationContext();
}
public void insert(final User user){
Completable.fromAction(() -> userDb.userDao().insert(user))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
Intent i = new Intent(ctx,MainActivity.class);
ctx.startActivity(i);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(ctx,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
public LiveData<List<User>> getAllUsers(){
return allUsers;
}
}
有人请帮我看看我怎样才能达到我想要的result.Any帮助将不胜感激。
谢谢
从存储库 class 切换 activity 我们需要将以下标志添加到 Intent。
这是更新的 onComplete() 方法。
@Override
public void onComplete() {
Intent i = new Intent(ctx,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
ctx.startActivity(i);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
希望对您有所帮助。
谢谢
在存储库中启动 activity 不是好的做法。您需要在 activity 中开始一个 activity。如果您想使用应用程序 Context 启动 activity,您应该使用 Intent.FLAG_ACTIVITY_NEW_TASK
。因为使用 默认标志 从应用程序的 Context
启动 activity 会阻止活动(层次结构)的 back stack。我建议使用 observables 像 RxJava 的 Observable
或 AAC 中的 LiveData
来通知 activity,并启动另一个 activity 在上面。 LivaData
怎么做?
更新 insert
方法如下:
public LiveData<Boolean> insert(final User user){
MutableLiveData<Boolean> isComplated = new MutableLiveData<>();
Completable.fromAction(() -> userDb.userDao().insert(user))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
isComplated.setValue(true);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(ctx,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
return isComplated;
}
在AddUser
activityclass中观察这个:
viewModel.insert(myUser).observe(this, isComplated -> {
if (isComplated != null && isComplated) {
Intent i = new Intent(AddUser.this, MainActivity.class);
ctx.startActivity(i);
}
});
编辑:
ViewModel class 应包含以下方法:
public LiveData<Boolean> insert(User user) {
return userRepositoryInstance.insert(user);
}
应该会有帮助=)
我正在为应用程序实施 MVVM 架构模式 development.I 有两个活动 MainActivity 和 AddUser activity.In MainActivity 我正在显示所有笔记的列表,在 AddUser activity 我在 room[=43= 中插入用户] database.I 正在存储库中执行所有插入和获取注释操作 class.I 正在使用 RxJava Completable 运算符在数据库中插入注释。
我想要的:插入后它应该重定向到 MainActivity。
问题: 使用 Intent 时无法在 onComplete() 方法中添加 Intent,它显示错误。
错误
Process: com.app.notesreactive, PID: 3970
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.
下面是我的代码:
UserDao.java
@Dao
public interface UserDao {
@Insert
void insert(User user);
@Query("SELECT * FROM Users ORDER BY id DESC")
LiveData<List<User>> getAllUsers();
}
UserRepository.java
public class UserRepository {
private UserDb userDb;
private UserDao userDao;
private LiveData<List<User>> allUsers;
private Context ctx;
public UserRepository(Application application) {
userDb = UserDb.getInstance(application);
userDao = userDb.userDao();
allUsers = userDao.getAllUsers();
ctx = application.getApplicationContext();
}
public void insert(final User user){
Completable.fromAction(() -> userDb.userDao().insert(user))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
Intent i = new Intent(ctx,MainActivity.class);
ctx.startActivity(i);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(ctx,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
public LiveData<List<User>> getAllUsers(){
return allUsers;
}
}
有人请帮我看看我怎样才能达到我想要的result.Any帮助将不胜感激。
谢谢
从存储库 class 切换 activity 我们需要将以下标志添加到 Intent。 这是更新的 onComplete() 方法。
@Override
public void onComplete() {
Intent i = new Intent(ctx,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
ctx.startActivity(i);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
希望对您有所帮助。
谢谢
在存储库中启动 activity 不是好的做法。您需要在 activity 中开始一个 activity。如果您想使用应用程序 Context 启动 activity,您应该使用 Intent.FLAG_ACTIVITY_NEW_TASK
。因为使用 默认标志 从应用程序的 Context
启动 activity 会阻止活动(层次结构)的 back stack。我建议使用 observables 像 RxJava 的 Observable
或 AAC 中的 LiveData
来通知 activity,并启动另一个 activity 在上面。 LivaData
怎么做?
更新 insert
方法如下:
public LiveData<Boolean> insert(final User user){
MutableLiveData<Boolean> isComplated = new MutableLiveData<>();
Completable.fromAction(() -> userDb.userDao().insert(user))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
isComplated.setValue(true);
Toast.makeText(ctx,"Data inserted", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(ctx,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
return isComplated;
}
在AddUser
activityclass中观察这个:
viewModel.insert(myUser).observe(this, isComplated -> {
if (isComplated != null && isComplated) {
Intent i = new Intent(AddUser.this, MainActivity.class);
ctx.startActivity(i);
}
});
编辑: ViewModel class 应包含以下方法:
public LiveData<Boolean> insert(User user) {
return userRepositoryInstance.insert(user);
}
应该会有帮助=)