我们在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;
}
寻求帮助,因为链只订阅,没有达到进一步的执行。
你static CompositeDisposable disposables
AbsViewModel
这就是这种奇怪行为的原因。这样做不是好主意,因为ViewModel
的所有实例都可以访问同一个disposables
实例 - 可以dispose()
并重新创建它。
让我们看一个例子:我们有 2 个屏幕,具有单独的ViewModel
(从AbsViewModel
扩展)。当您从第一个屏幕切换到第二个屏幕并返回第一个屏幕时,您将获得下一个跟踪:
- 屏幕1
ViewModel.attach()
- 屏幕2
ViewModel.attach()
- 屏幕1
ViewModel.attach()
- 触发
disposables.dispose()
的屏幕 1ViewModel.onCleared()
在这种情况下,在步骤 (3) 中,您将重新创建disposables
并添加新的,但在下一步 (4) 中,您将立即处理它。
这只是一种可能的情况,它指出了在所有AbsViewModel
实例之间共享的static
一次性用品的问题。如果从disposables
中删除static
修饰符以及使用它的所有方法 - 您的问题将消失。