rizmaulana / kotlin-mvvm-covid19

This repository contains simple COVID19 data monitoring with android stack MVVM, Live Data, Koin, RxJava, RxBinding, Offline first with simple caching, etc
Apache License 2.0
435 stars 111 forks source link

Rx without subscribeOn and observeOn #12

Closed fajarnuha closed 4 years ago

fajarnuha commented 4 years ago

As I see from our project, I barely see subscribeOn and observeOn in api call, how is this possible? even in DetailViewMode, it calls api with .subscribeOn(schedulerProvider.ui()) 😲

but the weird part is everything is working just fine, what am I missing here? @rizmaulana

rizmaulana commented 4 years ago
  1. No need to add subscribeOn on api call because it is already subscribe on io threads when retrofit initialized, here : https://github.com/rizmaulana/kotlin-mvvm-covid19/blob/master/app/src/main/java/id/rizmaulana/covid19/di/NetworkModule.kt
    .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
  2. Actually we also no need observeOn(schedulerProvider.ui()) because observe method on live data already force to running on main thread, we can see how observe method works here
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
  1. .subscribeOn(schedulerProvider.ui()) on DetailViewMode : silly me 😅 it must be . observeOn(schedulerProvider.ui()), but fortunately we use live data that makes view running on main thread. So it is not breaking. But why it also not blocked the api call when subscribe on mainThread()? AFAIK, RxJava only accepts first subscribeOn declaration (which is already on io thread) so code .subscribeOn(schedulerProvider.ui()) is ignored, CMIIW
fajarnuha commented 4 years ago

oh interesting, its very useful information, thanks

fajarnuha commented 4 years ago

perhaps you can turn this issue thread into task to remove the confusing part @rizmaulana

fajarnuha commented 4 years ago

and maybe schedulers wont be used in this scenario, how do we test? rxplugins if im not mistaken? itll be great if someone tries testing this @isfaaghyth

isfaaghyth commented 4 years ago

already test it, you can see the test case for DashboardViewModel, there's no issue for that