我在订阅取消订阅时执行某些逻辑时遇到了一些麻烦。我已经在这几个小时了,到目前为止我没有取得什么进展。这是我的代码的简化版本:
public class Command<E> {
public CommandActionObservable execute() {
final CommandAction<E> command = createCommand();
final OnSubscribe<CommandAction<E>> onSubscribe = (subscriber) -> {
/* Create a listener that handles notifications and register it.
* The idea here is to push the command downstream so it can be re-executed
*/
final Listener listener = (event) -> {
subscriber.onNext(command);
}
registerListener(listener);
/* This is where I'm having trouble. The unregister method
* should be executed when the subscriber unsubscribed,
* but it never happens
*/
subscriber.add(Subscriptions.create(() -> {
unregisterListener(listener);
}));
// pass the initial command downstream
subscriber.onNext(command);
kickOffBackgroundAction();
}
final Observable<CommandAction<E>> actionObservable = Observable.create(onSubscribe)
.onBackpressureLatest()
.observeOn(Shedulers.io())
.onBackpressureLatest();
return new CommandActionObservable((subscriber) -> {
actionObservable.unsafeSubscribe(subscriber);
})
}
public class CommandActionObservable extends Observable<CommandAction<E> {
// default constructor omitted
public Observable<E> toResult() {
return lift((Operator) (subscriber) -> {
return new Subscriber<CommandAction<E>>() {
// delegate onCompleted and onError to subscriber
public void onNext(CommandAction<E> action) {
// execute the action and pass the result downstream
final E result = action.execute();
subscriber.onNext(result)
}
}
}
}
}
}
我以通常的方式使用Command
,将生成的订阅添加到CompositeSubscription
并在onDestroy()
中取消订阅。这是一个例子:
final Observable<SomeType> obs = new Command<SomeType>()
.execute()
.toResult();
subscription.add(obs.subscribe(// impl here));
public void onDestroy() {
super.onDestroy();
subscription.unsubscribe();
}
如上所述,我无法使取消订阅逻辑工作并取消注册侦听器,这会导致应用程序中的内存泄漏。如果我在doOnUnsubscribe()
上调用obs
它会被调用,所以我没有正确地解释,但是可能嵌套可观察量和提升会导致一些问题。
我很乐意对此发表意见。
答案 0 :(得分:1)
事实证明这比我预想的要容易得多。
经过一番挖掘后,我能够自己拿出答案。只是发布给那些可能最终和我一样的人。
所以,正如我在我的问题中所提到的,如果我在我的doOnSubscribe()
中添加了Activity
动作,我会收到通知。接下来,我尝试在内部Observables
上添加相同的操作,我在execute()
方法中创建。他们没有被召唤。所以,我得出的结论是,在我的活动中的观察者和我在execute()
中创建的可观察者之间的链条被破坏了。
流中唯一发生的事情是我在Operator
中实施的自定义toResult()
的应用。在Google搜索之后,我发现了这篇优秀的文章 - Pitfalls of Operator Implementation。我确实在我的操作员中制动了链条,上游的观察者没有收到取消订阅的通知。
在我做了作者建议之后,一切都很好。这是我需要做的:
lift((Operator) (subscriber) -> {
// connect the upstream and downstream subscribers to keep the chain intact
new Subscriber<CommandAction<E>>(subscriber) {
// the implementation is the same
}
}