티스토리 뷰
참조
https://proandroiddev.com/singleliveevent-to-help-you-work-with-livedata-and-events-5ac519989c70
SingleLiveEvent를 사용하게 된 이유 : LiveData를 적용하는데 있어서 Trigger용... 그러니깐... 한번 상태가 변경된 후에 다시 이전 상태로 돌아와야 하는 경우가 생겼다. 그런데 이러한 Trigger용을 화면에 계속적으로 노출시키는 LiveData로 표현하려니 불편했달까...?? 마침 MutableLiveData와 MediatorLiveData 사용 방법 등을 찾던 와중에 SingleLiveEvent라는 것이 있다는 것을 얼핏 알고 있었는데, SingleLiveEvent를 이럴 때 사용한다는 것을 깨달았다.
그래서 SingleLiveEvent 사용 방법을 알아보고 적용하기로 하였다.
SingleLiveEvent : MutableLiveData의 확장버전으로 한번 변경이 일어난 후 다시 원래 상태로 변경되도록 한다.
사용 이유
예를 들어, 전체화면과 상세화면이 있다고 가정하자. (참조 블로그의 내용이자 내가 지금 개발하는 부분...)
위의 그림은 한 번만 이용.. 즉, Trigger로 LiveData를 이용했을 경우에 발생하는 문제점 중 하나이다.
이와 같은 문제점을 해결하기 위해서 Trigger(상태변경 감지 후, 상세화면으로 넘기는 형태) 직전에 LiveData의 값을 다시 초기화 시켜줘서 해결할 수 있다.
그러나 이러한 처리 방법은 bolierplate code를 발생시키며, 적용하는 것을 잊어버릴 수도 있다.
그렇기 때문에 SingleLiveEvent 사용을 권고한다.
※ SingleLiveEvent는 단 하나의 observer만 관찰할 수 있도록 한다. 만약 여러 observer가 관찰하도록 한다면, wrapper를 사용하라고 한다. 그 이유는 여러 observer가 변경사항을 관찰했을 때, 단 한번만 실행된다는 보장이 없기 때문이라는데... 이 부분은 잘 이해가 안된다...
https://gist.github.com/JoseAlcerreca/5b661f1800e1e654f07cc54fe87441af#file-event-kt
SingleLiveEvent 코드
SingleLiveEvent 코드는 android architecture-sample에서 발췌한것이다.
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.util.Log;
import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* A lifecycle-aware observable that sends only new updates after subscription, used for events like
* navigation and Snackbar messages.
* <p>
* This avoids a common problem with events: on configuration change (like rotation) an update
* can be emitted if the observer is active. This LiveData only calls the observable if there's an
* explicit call to setValue() or call().
* <p>
* Note that only one observer is going to be notified of changes.
*/
public class SingleLiveEvent<T> extends MutableLiveData<T> {
private static final String TAG = "SingleLiveEvent";
private final AtomicBoolean mPending = new AtomicBoolean(false);
@MainThread
public void observe(LifecycleOwner owner, final Observer<? super T> observer) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
}
// Observe the internal MutableLiveData
super.observe(owner, new Observer<T>() {
@Override
public void onChanged(@Nullable T t) {
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t);
}
}
});
}
@MainThread
public void setValue(@Nullable T t) {
mPending.set(true);
super.setValue(t);
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
public void call() {
setValue(null);
}
}
'android' 카테고리의 다른 글
[android] AlarmManager 등록 확인 방법 (0) | 2020.08.31 |
---|---|
[android] data binding - 객체 식별 (0) | 2020.07.27 |
[android] data binding error 문제 해결 방법 (0) | 2020.07.18 |
[Google I/O] Fun with LiveData (Android Dev Summit '18) 정리 (0) | 2020.07.13 |
[Google I/O] 2016 - Advanced Data Binding ( + 20분 이후부터는 추가 예정 ) (0) | 2020.07.10 |