【发布时间】:2017-02-07 08:43:38
【问题描述】:
我正在尝试实现一个计时器Observable,它在我的应用程序的Activities 之间共享。我正在一个作为 Dagger 单例的类上进行实现,我在每个不同的Activity 的每个Presenter 中注入它。
我用这种方式创建了一次 Observable:
Observable.defer(() -> Observable.timer(milliseconds, TimeUnit.MILLISECONDS).map(t -> this::doSomethingCool()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.share();
我使用以下功能从 Presenter 进行订阅:
public Observable<Status> register(Callback callback) {
PublishSubject<Status> subject = PublishSubject.create();
subject.subscribe(status -> {},
throwable -> L.LOGE(TAG, throwable.getMessage()),
() -> callback.onStatusChanged(mBasketStatus));
mObservable.subscribe(subject);
basketCounterCallback.onStatusChanged(status));
subject.doOnUnsubscribe(() -> L.LOGD(TAG, "Unsubcribed from subject!"));
return subject.asObservable();
}
我将 Subject 存储为 Observable 在每个演示者中,我打电话给:
obs.unsubscribeOn(AndroidSchedulers.mainThread())
取消订阅(在onPause() 方法中)。我还尝试使用调度程序取消订阅Schedulers.immediate()
但是无论如何都会调用回调 X 次(其中 X 是我已订阅计时器的所有 Presenter),因此它不会取消订阅。日志"Unsubcribed from subject!" 也没有被调用。
如何正确退订每个主题?
提前致谢
编辑:
由于 cmets 添加了更多实现细节:
这是我创建 Observable 并将其存储在 Singleton 类 StatusManager 的成员中的部分(状态也是单例):
private Observable<BasketStatus> mObservable;
private Status mStatus;
public Observable<BasketStatus> start(long milliseconds, Status status, Callback callback) {
if (mObservable == null) mObservable = createObservable(milliseconds, status);
return register(callback);
}
private Observable<BasketStatus> createObservable(long milliseconds, Status status) {
mStatus = status;
return Observable.defer(() -> Observable.timer(milliseconds, TimeUnit.MILLISECONDS).map(t -> status.upgradeStatus()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.share();
}
public Observable<BasketStatus> register(Callback callback) {
PublishSubject<Status> subject = PublishSubject.create();
subject.subscribe(status -> {},
throwable -> L.LOGE(TAG, throwable.getMessage()),
() -> callback.onStatusChanged(mStatus));
mObservable.subscribe(subject);
callback.onStatusChanged(mStatus));
subject.doOnUnsubscribe(() -> L.LOGD(TAG, "Unsubcribed from subject!"));
return subject.asObservable();
}
在从启动计时器的Presenter 调用方法start(...) 之后,我从下一个演示者调用register(...) 方法:
class Presenter implements Callback {
private Observable<BasketStatus> mRegister;
@Inject
public Presenter(Status status, StatusManager statusManager) {
mRegister = statusManager.start(20000, status, this);
}
// Method called from onPause()
public void unregisterFromBasketStatus() {
mRegister.unsubscribeOn(Schedulers.immediate());
}
}
还有下一位演讲者……
@Inject
public NextPresenter(StatusManager statusManager) {
mBasketStatusManager.register(this);
}
【问题讨论】:
-
让我们退后一步。你想达到什么目标?
-
我想知道定时器什么时候结束,并且只通知那一刻显示的活动,并且只有当应用程序打开时才通知。所以我认为服务不是解决方案,所以我想到了这个解决方案。
-
是
mObservable计时器吗? -
您的代码示例还不够。您退订了哪些 observable?由
register方法返回的那个还是存储在mObservable中的可观察计时器?另外,你真的在 onPause 方法中调用.unsubscribe()吗?在我看来,您似乎不明白unsubscribeOn()做了什么......它只是指示在特定调度程序上运行取消订阅任务。它不会以任何方式调用它..我可能对您的理解有误,这就是我们需要更多代码的原因.. -
@Blackbelt 是的!
标签: android rx-java observable rx-android subject-observer