Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LiveData remove Observer after first callback

How do I remove the observer after I receive the first result? Below are two code ways I've tried, but they both keep receiving updates even though I have removed the observer.

Observer observer = new Observer<DownloadItem>() {         @Override         public void onChanged(@Nullable DownloadItem downloadItem) {             if(downloadItem!= null) {                 DownloadManager.this.downloadManagerListener.onDownloadManagerFailed(null, "this item already exists");                 return;             }             startDownload();             model.getDownloadByContentId(contentId).removeObservers((AppCompatActivity)context);         }     };     model.getDownloadByContentId(contentId).observeForever(observer); 

 model.getDownloadByContentId(contentId).observe((AppCompatActivity)context, downloadItem-> {              if(downloadItem!= null) {                 this.downloadManagerListener.onDownloadManagerFailed(null, "this item already exists");                 return;             }             startDownload();             model.getDownloadByContentId(contentId).removeObserver(downloadItem-> {});         } ); 
like image 644
galaxigirl Avatar asked Dec 17 '17 11:12

galaxigirl


People also ask

How do I remove LiveData Observer?

You should manually call removeObserver(Observer) to stop observing this LiveData.

What is SingleLiveEvent?

SingleLiveEvent:- SingleLiveEvent is a subclass of MutableLiveData with a single Observer Observing it at a time, hence it is aware of view's lifecycle.

What is LiveData Observer?

LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.


Video Answer


1 Answers

There is a more convenient solution for Kotlin with extensions:

fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {     observe(lifecycleOwner, object : Observer<T> {         override fun onChanged(t: T?) {             observer.onChanged(t)             removeObserver(this)         }     }) } 

This extension permit us to do that:

liveData.observeOnce(this, Observer<Password> {     if (it != null) {         // do something     } }) 

So to answer your original question, we can do that:

val livedata = model.getDownloadByContentId(contentId) livedata.observeOnce((AppCompatActivity) context, Observer<T> {     if (it != null) {         DownloadManager.this.downloadManagerListener.onDownloadManagerFailed(null, "this item already exists");     }     startDownload(); }) 

The original source is here: https://code.luasoftware.com/tutorials/android/android-livedata-observe-once-only-kotlin/

Update: @Hakem-Zaied is right, we need to use observe instead of observeForever.

like image 63
Vince Avatar answered Nov 13 '22 23:11

Vince