Notice
Recent Posts
Recent Comments
Link
투케이2K
344. (TWOK/ERROR) [Android] Cannot invoke setValue on a background thread IllegalStateException 본문
투케이2K 에러관리
344. (TWOK/ERROR) [Android] Cannot invoke setValue on a background thread IllegalStateException
투케이2K 2026. 2. 13. 17:13728x90
반응형
[환경 설정 및 설명]
프로그램 : Android / 안드로이드
설 명 : [Android] Cannot invoke setValue on a background thread IllegalStateException

[설 명]
--------------------------------------------------------------------------
[개발 및 테스트 환경]
--------------------------------------------------------------------------
- 제목 : [Android] Cannot invoke setValue on a background thread IllegalStateException
- 테스트 환경 : 삼성 갤럭시 스마트폰 / 안드로이드 / Android / RxJava / LiveData
- 사전) RxJava 설명 :
>> Rx (ReactiveX) :
- ReactiveX 는 관찰가능한 절차를 통해 비동기, 이벤트 기반 프로그램을 구성하기 위한 라이브러리 입니다
- ReactiveX 는 Observer Pattern 옵저버 패턴 을 확장하며, Sequence 를 조합할 수 있는 연산자를 지원합니다
- ReactiveX 는 low-level Thread, 동기화, Thread 안전성, non-blocking I/O 에 관한 우려를 줄입니다
>> RxJava (Reactive java) :
- Reactive Programming 패러다임을 자바에서 구현한 프로그래밍 라이브러리 입니다
- RxJava 는 함수형 프로그래밍 방식을 도입했으며, Side Effect 가 없는 순수 함수를 지향하기 때문에 Thread-Safe 합니다
--------------------------------------------------------------------------
--------------------------------------------------------------------------
[에러 원인]
--------------------------------------------------------------------------
1. LiveData/MutableLiveData 의 setValue() 를 메인 (UI) 스레드에서만 호출해야 하는데, 백그라운드 스레드에서 호출되어 발생하는 이슈
2. ❌ 에러 발생 로그 전문 :
>> Cannot invoke setValue on a background thread
java.lang.IllegalStateException: Cannot invoke setValue on a background thread
3. ✅ 참고 추가 설명 : LiveData/MutableLiveData 의 setValue() vs postValue() 차이
>> setValue(T value)
- 메인 스레드에서만 호출 가능
- 즉시 옵저버에 전달
>> postValue(T value)
- 어느 스레드에서든 호출 가능
- 메인 스레드로 전달되어 비동기 업데이트
- 여러 번 연속 호출 시 마지막 값만 전달될 수 있음 (중간값이 coalesce 될 수 있음)
--------------------------------------------------------------------------
--------------------------------------------------------------------------
[해결 방법]
--------------------------------------------------------------------------
방법 [1] : 백그라운드 스레드 (예: I/O, 네트워크, Room 쿼리, 코루틴 Dispatchers.IO) 에서는 setValue 대신 postValue 를 사용해 데이터 메인 스레드로 전달 처리
>> setValue() ❌ (금지)
>> postValue() ✅ (스레드 안전, 내부적으로 메인 스레드로 전달)
방법 [2] : 메인 스레드로 컨텍스트 전환 후 setValue() 호출 처리
>> 코루틴 withContext(Dispatchers.Main) / viewModelScope.launch(Dispatchers.Main)
>> Handler(Looper.getMainLooper())
>> RxJava observeOn(AndroidSchedulers.mainThread())
예시 소스 코드 [RxJava] : Observable 생성 후 subscribe 에서 AndroidSchedulers mainThread 처리 수행
// -----------------------------------------------
// [Observable create 사용해 생성 실시 : 생성자]
// -----------------------------------------------
// Observable<String> : String 값 onNext 반환 수행
// -----------------------------------------------
Observable<String> observable = Observable.create(subscriber -> {
try {
if (!subscriber.isDisposed()) { // ✅ [연결된 구독자가 있는 경우]
// [onNext] 데이터 알림 전달
subscriber.onNext("SUCCESS");
// [onCompleted] 완료 알림 전달
subscriber.onComplete();
}
} catch (Exception e) {
e.printStackTrace();
// ❌ [onError] 에러 알림 전달
subscriber.onError(e);
}
});
// -----------------------------------------------
// -----------------------------------------------
// [Observable 생성자 를 구독 (Subscribe) 및 데이터 소비 수행]
// -----------------------------------------------
Disposable disposable = observable
.subscribeOn(Schedulers.io()) // (선택) 데이터 생성/업스트림을 백그라운드로 수행
.observeOn(AndroidSchedulers.mainThread()) // ✅ 구독 콜백을 메인 스레드에서 실행
.subscribe(
value -> { // ✅ onNext 응답 처리
S_Log.d("KWON_TWOK", ">>>>>>>>>>>>>>>>>>>> [Observable] : [onNext] : " + String.valueOf(value) + " >>>>>>>>>>>>>>>>>>>>");
resUpdate.setValue(sendResponseData); // TODO 리턴 반환
},
error -> { // ❌ onError 응답 처리
S_Log.e("KWON_TWOK", ">>>>>>>>>>>>>>>>>>>> [Observable] : [onError] : " + String.valueOf(error.getMessage()) + " >>>>>>>>>>>>>>>>>>>>");
resUpdate.setValue(sendErrorData); // TODO 에러 반환
},
() -> { // ✅ onCompleted 응답 처리
S_Log.w("KWON_TWOK", ">>>>>>>>>>>>>>>>>>>> [Observable] : [onCompleted] >>>>>>>>>>>>>>>>>>>>");
}
);
--------------------------------------------------------------------------
--------------------------------------------------------------------------
[참고 사이트]
--------------------------------------------------------------------------
[Observable] create 사용해 생성자 만들기 및 subscribe 구독 결과 메시지 확인
https://kkh0977.tistory.com/3599
https://blog.naver.com/kkh0977/222970344668?trackingCode=blog_bloghome_searchlist
[Observable] just 사용해 생성자 만들기 및 subscribe 구독 결과 메시지 확인
https://blog.naver.com/kkh0977/222970341475?trackingCode=blog_bloghome_searchlist
[Subject] AsyncSubject 사용해 onNext() 발행 된 마지막 데이터 출력 실시
https://blog.naver.com/kkh0977/222970372557?trackingCode=blog_bloghome_searchlist
--------------------------------------------------------------------------
728x90
반응형
'투케이2K 에러관리' 카테고리의 다른 글
Comments
