在将订阅添加到RxAndroid(可观察)中的一次性后,控制流程将结束,而无需调用订阅。

时间:2018-08-13 10:39:31

标签: android rx-java rx-java2 dagger-2 rx-android

我正在尝试在Android中使用MVP,RX和Dagger 2。以下是代码流,

LocalDataSource.java

@Singleton
public class LocalDataSource implements DataSource {

@Override
public Observable getServerSettings() {
return mDBHelper.createQuery(ServerSettingsEntry.TABLE_NAME,
DbUtils.getSelectAllQuery(ServerSettingsEntry.TABLE_NAME))
.mapToOne(DbUtils::getServerSettings);

Repository.java

@Singleton
public class MyRepository implements DataSource {
@Override
    public Observable<ServerSettings> getServerSettings() {
        return mLocalDataSource.getServerSettings().compose(RxUtils.applySchedulers());

LoginPresenter.java

public class LoginPresenter implements LoginActivityContract.Presenter{
 @Override
    public void checkServerDbSynced() {
        mCompositeDisposable.clear();
        Disposable subscription = mRepository
                .getServerSettings()
                .doOnSubscribe(disposable -> {
                    Timber.d(" onSubscribe");
                    mView.showLoadingIndicator(true, "Checking Server ....");
                })
                .subscribe(serverSettings -> {
                            if (serverSettings == null) {
                                Timber.d("*** Server Db Synced ****" + "\n" + "*** Checking Licence Key **** ");
                                checkLicenceKey();
                                } else {
                                Timber.d("*** Server Db Not Synced *** " + " \n" + "*** Opening Login Dialog ****");
                                mView.showLoadingIndicator(false, "Db Not Synced ....");
                                mView.openLoginDialog();
                                }
                                },
                        throwable -> {
                            mView.showErrorMessage(throwable.getLocalizedMessage());
                            });
        mCompositeDisposable.add(subscription);
    }
}



    @Override
    public void subscribe() {
        checkServerDbSynced();
    }

    @Override
    public void unSubscribe() {
        mCompositeDisposable.clear();
    }

问题是未调用subscribe中的语句。调试时,我注意到在这行之后 compositepossible.add(subscription);控制流程结束了……请帮助... !!

修改

public static ServerSettings getServerSettings(@NonNull Cursor cursor) {
ServerSettings s = new ServerSettings();
        s.setAndroidId("1234564453453463dfg");
                s.setDeviceId("tythyerju99");
                s.setIpAddress("6373792092.48949");
                s.setLicenceKey("fhfhdid");
                s.setExpiryDate("hshsh8ehd8");
                s.setId(2);
        Timber.d(" *** " +s.getExpiryDate()+" ****");
        return s;
    }

1 个答案:

答案 0 :(得分:1)

您的doOnSubscribe在执行getServerSettings()的同一线程上执行内容,该线程属于Schedulers.io()。因此,您的mView.showLoadingIndicator(true, "Checking Server ....")试图通过主线程更新UI(这是不允许的),因此此错误会终止您的Observable执行-您可能会在mView.showErrorMessage(throwable.getLocalizedMessage())调用中看到它,但是我不知道你到底在做什么。

您应该做的是按照以下步骤将消息从doOnSubscribe发送到主线程:

...
            .doOnSubscribe(disposable -> {
                Timber.d(" onSubscribe");
                new Handler(Looper.getMainLooper()).post(() -> {
                    mView.showLoadingIndicator(true, "Checking Server ....");
                });
            })
...

更新

在讨论之后发现,问题出在LocalDataSourcegetServerSettings方法中。具体来说,在使用mapToOne时。当结果集为空时,则没有东西要发出,这就是为什么未调用subscribe使用者方法的原因。为了确保不会发生这种情况,请使用maptoOneOrDefault,如果结果集为空,它会发出指定的默认值。