NetworkOnMainThread thrown when performing a clear from the MainThread
LarsWerkman opened this issue · comments
When performing a clear from the MainThread while Observing a getRefreshing Observable the NetworkOnMainThread exception is thrown while fetching from an Api.
Here is a broken down example:
favoriteShopsStore = StoreBuilder.<String, BufferedSource, List<Shop>>parsedWithKey()
.fetcher(ignore -> api.getFavoriteShops())
.memoryPolicy(MemoryPolicy.builder()
.setExpireAfterWrite(1)
.setExpireAfterTimeUnit(TimeUnit.HOURS)
.setMemorySize(1)
.build())
.refreshOnStale()
.open();
favoriteShopsStore.getRefreshing("favorite")
.subscribeOn(io.reactivex.schedulers.Schedulers.io())
.observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Shop>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<Shop> shops) {
}
@Override
public void onError(Throwable e) {
//Error on NetworkOnMainThread is thrown
}
@Override
public void onComplete() {
}
});
favoriteShopsStore.clear("favorite");
This exception isn't thrown when you force the api call to always subscribe on the IO schedulers, however it seems to me that this isn't as intended.
.fetcher(ignore -> api.getFavoriteShops().subscribeOn(Schedulers.io()))
I traced it down to the RealInternalStore::response
method
@Nonnull
Single<Parsed> response(@Nonnull final Key key) {
return fetcher()
.fetch(key)
.flatMap(raw -> persister()
.write(key, raw)
.flatMap(aBoolean -> readDisk(key).toSingle()))
.onErrorResumeNext(throwable -> {
if (stalePolicy == StalePolicy.NETWORK_BEFORE_STALE) {
return readDisk(key)
.switchIfEmpty(Maybe.<Parsed>error(throwable))
.toSingle();
}
return Single.error(throwable);
})
.doOnSuccess(data -> notifySubscribers(data, key))
.doAfterTerminate(() -> inFlightRequests.invalidate(key))
.cache();
}
Here it seems the original exception is thrown inside the onErrorResumeNext
clause
Hmm. Wouldn't network on Main thread exception also be thrown if you call get from main thread? Overall store performs all operations on whatever thread the api is called. I'll make a getRefreshing override that takes in a scheduler.