기록
[GPT가 알려주는] setValue() 와 postValue()의 차이점 본문
지금처럼 일반적으로 registerReceiver(context, filter)로 등록한 BroadcastReceiver.onReceive()는 메인 스레드에서 호출되니까, 여기서는 setValue() 써도 안전하고 오히려 좋아요. (게이트/즉시 반영이 필요할 때 유리)
언제 setValue(), 언제 postValue()?
setValue() (메인 스레드 전용)
- 지금 이 케이스처럼 onReceive()(메인), 버튼 클릭, LiveData 옵저버 등 UI/메인 스레드에서 호출할 때.
- 바로 다음 로직에 영향을 줘야 할 때(게이트 변수, 즉시 필터링 등).
- 예: ACTION_DISCOVERY_STARTED/FINISHED에서 _isScanning을 곧바로 바꿔 즉시 FOUND/NAME_CHANGED를 거르고 싶을 때.
_isBluetoothOn.value = (state == BluetoothAdapter.STATE_ON) // setValue와 동일 (메인에서만)
postValue() (어떤 스레드든 OK)
- 백그라운드 스레드(IO, Worker, 콜백 스레드 등)에서 값 올릴 때.
- 즉시성 덜 중요하고, 메인 루퍼에서 조금 있다가 반영돼도 괜찮을 때.
- 연속 갱신이 많고 합쳐져도 되는 값(마지막 값만 의미 있음)일 때.
※ 주의: postValue()는 여러 번 빠르게 호출되면 마지막 값 하나만 전달됩니다(합쳐짐). 카운터처럼 누락되면 곤란한 값에는 부적합.
예외/주의
- 만약 registerReceiver(..., ..., ..., handler)처럼 핸들러를 따로 넘겨서 onReceive()가 메인이 아닌 스레드에서 돌게 해놨다면 → setValue()는 크래시, postValue() 써야 합니다.
- 확실히 하고 싶으면 체크 가능:
val onMain = Looper.myLooper() == Looper.getMainLooper()
if (onMain) _live.value = v else _live.postValue(v)
작게 팁 하나:
fun <T> MutableLiveData<T>.safeSet(v: T) {
if (Looper.myLooper() == Looper.getMainLooper()) value = v else postValue(v)
}
이렇게 쓰면 “어디서 부르든” 안전합니다.
'잡동사니 > GPT가 알려주는' 카테고리의 다른 글
| [GPT가 알려주는] Vendor Dependent | Bluetooth Music Player (AVRCP, MediaSession) (0) | 2025.09.11 |
|---|---|
| [GPT가 알려주는] 인셋(insets)이란? (0) | 2025.09.08 |
| [GPT가 알려주는] 코루틴과 Dispatchers (3) | 2025.07.31 |
| [GPT가 알려주는] adb로 내가 write한 변수 읽어오기 (3) | 2025.07.30 |
| [GPT가 알려주는] JVM에서 object는 싱글톤이다 (0) | 2025.07.30 |