0

当演示者触发此操作但演示者在查询结束之前处理可观察对象时,执行某种“后台”操作(例如将数据保存在数据库中)的正确方法是什么?

我应该将我的可观察存储库与用例分离吗?

例子

我正在使用 RxJava 和 Dagger 开发一个遵循 Clean Architecture 和 MVP 模式的 Android 应用程序。

在对话框中,我列出了设备,并且在列表中选择它时可以连接到其中一个。当单击列表中的一个元素时,对话框被关闭,我正在将此设备设置/保存为我的存储库层中的“当前”设备,并在活动的工具栏中为徽标设置动画(有点像 Chromecast 正在做)。

在我的演示者中,我在视图分离时处置了我的用例,因此如果在关闭对话框时保存未完成,则可观察对象被处置并且设备未设置为“当前”设备。

主持人

@Override
public void deviceClicked(String id) {
    getMvpView().dismissView();
    mConnectToDeviceUseCase.execute(id, new DisposableCompletableObserver() {
        @Override
        public void onComplete() {
            Timber.d("Connected to device");
        }

        @Override
        public void onError(Throwable e) {
            Timber.e("Error while connecting to device: %s", e.getMessage());
        }
    });
}

用例

public class ConnectToDeviceUseCase extends UseCaseCompletableWithParameter<String, DevicesRepository> {

    @Inject
    public ConnectToDeviceUseCase(DevicesRepository DevicesRepository,
                                   @Named("Thread") Scheduler threadScheduler,
                                   @Named("PostExecution") Scheduler postExecutionScheduler) {
        super(devicesRepository, threadScheduler, postExecutionScheduler);
    }

    @Override
    protected Completable buildObservable(String id) {
        Timber.d("GetDevicesUseCase buildObservable");

        return repository.connectToDevice(id);
    }
}

存储库

private ReplaySubject<DeviceConnection> connectionStatus = ReplaySubject.create();

...

@Override
public Completable connectToDevice(String id) {
    Timber.d("connectToDevice IN");
    return mDLNADataSource.getDevices()
            .flatMapIterable(items -> items)
            .filter(item -> item.id().equals(id))
            .firstOrError()
            .flatMapCompletable(this::saveAsCurrent)
            .doOnSubscribe(a ->
                    {
                        Timber.d("connectToDevice doOnSubscribe");
                        connectionStatus.onNext(DeviceConnection.builder().setStatus(DeviceConnection.STATUS_CONNECTING).build());
                    }
            )
            .doOnComplete(() ->
                    {
                        Timber.d("connectToDevice doOnComplete");
                        connectionStatus.onNext(DeviceConnection.builder().setStatus(DeviceConnection.STATUS_CONNECTED).build());
                    }
            )
            .doOnError(a ->
                    {
                        Timber.d("connectToDevice doOnError");
                        connectionStatus.onNext(DeviceConnection.builder().setStatus(DeviceConnection.STATUS_NOT_CONNECTED).build());
                    }
            )
            .doOnDispose(() ->
            {
                Timber.d("connectToDevice doOnDispose");
            });

}
4

1 回答 1

0

我既不是 java 也不是 Android 专家,但你在问题中描述的内容对我来说听起来像是控制流问题。如果您触发一些异步活动(例如保存),您还应该将清理连接到它。一种可能的解决方案是使用“未来”或“承诺”的概念。另一种可能是参与者模式,其中保存和清理将是顺序执行的消息。

于 2018-02-01T21:01:47.710 回答