question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Observer being able to distinguish between new and "cached" data

See original GitHub issue

First off, the concept of having LiveData (and MutableLiveData) with observers that handle Lifecycle is a great addition on top of the bare metal Android components.

Having played around with LiveData and Observer there arrived one case where it would really be desirable to know if LiveData is passing on a cached version (mVersion) due to the change of LifecycleBoundObserver (initiator), this references the filed/param names in LiveData.java.

Following here is a case where it would be good to know if LiveData is cached or not:

It seems to be a good pattern to create LiveData that is private final and associate a getter with it, looks usually something like below:

private final MutableLiveData<ApiResponse<DownloadResponse>> mDownloadLiveData = new MutableLiveData<>();

A Fragment would then register an Observer on that LiveData

mViewModel.getDownloadLiveData().observe(this, mDownloadObserver);

mDownloadObserver in this case would also be private final inside Fragment

private final mDownloadObserver = new Observer ...

So far so good, the Code will notify the Observer when new data arrives and consider the applications Lifecycle.

However, as soon as the Fragment undergoes a configuration change, LiveData realizes that LifecycleBoundObserver has changed and mVersion does not match observer.lastVersion (in fact it has been initialized to -1) and thus publishes it’s underlying data mData with onChanged.

I am certain this is how it is intended, and indeed it seems that most applications expect this behavior. However in certain cases it would be desirable to know that the onChange has been fired with LifecycleBoundObserver.lastVersion = -1.

Of course placing a state variable in the Fragment would allow for checking if the Data has been manually requested, yet it seems to negate the purpose of the stateless design around the Architecture components.

A suggestion would be to have a second option that allows to register a stateful Observer knowing if the callback is issued due to a new LifeCycleBoundObserver.

public void observe(LifecycleOwner owner, StatefulObserver<T> observer) 

and

public interface StatefulObserver<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     * @param fromCache whether or not the value is submited due to a new LifeCycleBoundObserver
     */
    void onChanged(@Nullable T t, boolean fromCache);
}

Again thanks a lot and keep up the good work! Manuel

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
yigitcommented, Jun 25, 2017

You can check the SingleEvent class in this example: https://github.com/googlesamples/android-architecture/tree/dev-todo-mvvm-live We are thinking about moving it to the library.

1reaction
abhinav272commented, Aug 23, 2018

@yigit SingleEvent works fine but will it create any problems if I also add

@Override
    public void observeForever(@NonNull final Observer<T> observer) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
        }

        super.observeForever(new Observer<T>() {
            @Override
            public void onChanged(@Nullable T t) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t);
                }
            }
        });
    }

So if it is being used as a source to another MediatorLiveData it does not send events to onChanged() of the observer when orientation is changed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Observer being able to distinguish between new and "cached ...
First off, the concept of having LiveData (and MutableLiveData) ... Observer being able to distinguish between new and "cached" data #55.
Read more >
Why LiveData observer is being triggered twice for a newly ...
The observers method void onChanged(@Nullable T t) is called twice. That's fine. The first time it is called upon startup. The second time...
Read more >
Current desires of conspecific observers affect cache ... - NCBI
In the unseen condition of the caching experiment, we investigated what information led cachers to alter their caching behaviour. The procedure ...
Read more >
rx-cache-observer - npm
This package is intended to make caching easier for Angular HttpClient calls. It can be used to ensure a user interface is presented...
Read more >
Caching in ArcGlobe—ArcMap | Documentation
The caching process indexes and organizes your symbolized data into tiles and levels of detail. This technique, an integral part of ArcGlobe, allows...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found