我们在LoginViewModel
中获得了以下代码:
private MutableLiveData<Response> loginLiveData;
@Inject
public LoginViewModel(LoginUseCase loginUseCase) {
loginLiveData = new MutableLiveData<>();
this.loginUseCase = loginUseCase;
}
@Override
public void onAttached() {
checkHasToken();
}
public void checkHasToken() {
add(loginUseCase.hasToken()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> Timber.d("doOnComplete"))
.doFinally(() -> Timber.d("doFinally"))
.doOnDispose(() -> Timber.d("doOnDispose"))
.doOnTerminate(() -> Timber.d("doOnTerminate"))
.doOnError(Timber::d)
.doOnSubscribe(disposable -> Timber.d("doOnSubscribe " + disposable.isDisposed()))
.subscribe(
() -> {
loginLiveData.setValue(Response.success());
Timber.d("Subscribe completable");
},
t -> {
loginLiveData.setValue(Response.error(t));
Timber.d("Subscribe error");
}
)
);
}
hasToken()
只是在SharedPreferences
中检查令牌是否存在:
public Completable hasToken() {
return !TextUtils.isEmpty(rawToken()) ? Completable.complete() : Completable.error(new Throwable("TokenIsEmpty");
}
代码成功运行,如日志所示:
D/LoginViewModel: doOnSubscribe false
D/LoginViewModel: doOnComplete
D/LoginViewModel: doOnTerminate
D/LoginViewModel: Subscribe completable
D/LoginViewModel: doFinally
尽管如此,几次却什么也不执行,日志如下所示:
D/LoginViewModel: doOnSubscribe false
仅此而已! 屏幕停留在这一点上,并且不进行进一步的逻辑处理。 它也发生在其他屏幕上。
我的基础ViewModel
如下:
public abstract class AbsViewModel extends AndroidViewModel {
private static CompositeDisposable disposables;
public AbsViewModel(@NonNull Application application) {
super(application);
}
public AbsViewModel() {
super(null);
}
public void onAttached() {}
@Override
public void onCleared() {
dispose();
super.onCleared();
}
public static void add(Disposable disposable) {
getCompositeDisposable().add(disposable);
}
protected void dispose() {
disposables.dispose();
disposables.clear();
}
public static void dispose() {
Timber.d("dispose");
getCompositeDisposable().dispose();
}
private static CompositeDisposable getCompositeDisposable() {
if (disposables == null || disposables.isDisposed()) {
disposables = new CompositeDisposable();
}
return disposables;
}
寻求帮助,因为该链仅被订阅,无法进一步执行。
答案 0 :(得分:1)
您在static CompositeDisposable disposables
中有AbsViewModel
是造成这种奇怪行为的原因。这样做不是个好主意,因为ViewModel
的所有实例都可以访问disposables
的相同实例-可以dispose()
并重新创建它。
让我们看一个例子:我们有2个屏幕,分别带有ViewModel
(从AbsViewModel
扩展)。从第一个屏幕切换到第二个屏幕并返回到第一个屏幕时,将获得下一个跟踪:
ViewModel.attach()
ViewModel.attach()
ViewModel.attach()
ViewModel.onCleared()
触发disposables.dispose()
在这种情况下,您将在步骤(3)中重新创建disposables
并添加新的,但是在下一步(4)中,您将立即处理它。
这只是可能的情况之一,它指出了static
的所有实例之间共享的AbsViewModel
一次性用品的问题。如果您从static
中删除disposables
修饰符,并且使用所有修饰符,您的问题将消失。