I have an observable:
public Observable<List<Conversation>> getConversationListObservable() {
return Observable.create(emitter -> {
List<Conversation> conversations = networkApi.getConversations();
for (Conversation conversation : conversations) {
if (emitter.isDisposed()) return; // this will cause subscription to terminate.
List<User> users = networkApi.getUserList(conversation.getId());
conversation.setUsers(users);
}
emitter.onNext(conversations);
emitter.onComplete();
});
}
which is used in androidx.lifecycle.ViewModel
class:
public class ConversationViewModel extends ViewModel {
private CompositeDisposable disposables = new CompositeDisposable();
....
public void fetchConversationList(){
disposables.add(repository.getConversationListObservable()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::setConversations, this::onError));
}
}
When I go away from the screen with a list of Conversation
, this observable is disposed, but I have a warning in logcat
from RxJavaPlugins.setErrorHandler
placed in my Application
class:
W/RxJavaPlugins.setErrorHandler - Undeliverable exception received, not sure what to do: java.lang.InterruptedException
on networkApi.getUserList
call. Seems like when I make this network call my subscriber is not disposed at the beginning of the network call and is already disposed when I am getting response on the call. Is there a way to do not get InterruptedException
in RxJavaPlugins.setErrorHandler
except of removing this plugin from Application
class?
P.S.: Stack trace looks like:
2019-11-24 23:28:00.152 18051-18343/com.example W/RxJavaPlugins.setErrorHandler - Undeliverable exception received, not sure what to do: java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1036)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1327)
at scala.concurrent.impl.Promise$DefaultPromise.tryAwait(Promise.scala:212)
at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:222)
at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:227)
at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
at scala.concurrent.Await$.result(package.scala:190)
at com.example.client.Client.sendRequest(Client.scala:61)
at com.example.ui.Repository.provideClient(Repository.java:205)
at com.example.ui.Repository.fetchUser(Repository.java:981)
at com.example.ui.Repository.fetchUserWithRole(Repository.java:987)
at com.example.ui.Repository.access$2400(Repository.java:95)
at com.example.ui.Repository$11.lambda$createCall$1$Repository$11(Repository.java:912)
at com.example.ui.-$$Lambda$Repository$11$8ZJhKkqn7hg2E6f5A5NBX1EeUPY.subscribe(lambda)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableOnErrorNext.subscribeActual(ObservableOnErrorNext.java:38)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
It is a stack trace from the real code, but I have simplified the code for the present question. Client.sendRequest
in this stack trace corresponds to networkApi.getUserList
in the simplified example.