문제점
스레드가 돌다가 특정 조건을 만족하면 토스트를 띄우게 하려고 했으나, 다음과 같은 예외가 발생한다.
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
이유
UI에 영향을 주는 스레드는 메인스레드가 담당한다.
그 이유를 찾아보고 이해한 바는 다음과 같다.
만약의 (그림 1) 처럼 하나의 UI Control에 하나 이상의 스레드가 동시에 접근하여 값을 변경한다고 가정해보자. 이때 TextView는 어떤 값을 반영하여 사용자에게 보여줄 것인가? 이를 방지 하기 위해 메인스레드에서만 UI 관련 작업을 수행할 수 있는 것이다.
해결책
그렇다고 스레드 내에서 토스트를 아예 띄울 수 없는 것은 아니다.
내가 찾아본 방법은 2가지가 있다.
1. Looper 사용하기
2. RunonUIThread
1. Looper 사용하기
Looper.prepare() / Looper.loop() 를 사용하는 방법이다.
예)
Looper.prepare();
Toast.makeText(MainActivity.this, "Custom Message", Toast.LENGTH_LONG).show();
Looper.loop();
2. runOnUIThread 메소드 호출하기
현재 스레드가 UI스레드이면 바로 실행하고 아니면 핸들러가 이를 UI스레드로 보내 이벤트큐에 집어 넣게 된다.
예)
runOnUIThread(new Runnable(
public void run() {
Toast.makeText(MainActivity.this, "Custom Message", Toast.LENGTH_LONG).show();
}
));
나같은 경우 이유는 모르겠지만 아마 다른 스레드가 백그라운드에서 너무 많이 돌아가서 그런지 몰라도 방법1은 잘 통하지 않았다. 그래서 방법2로 적용하였다.
'개발 관련 이야기' 카테고리의 다른 글
[NSIS] 자동실행 시 파라미터 전달 (0) | 2022.08.05 |
---|---|
Window - 환경변수 설정 없이 Visual Studio에서 OpenCV 사용하기 (0) | 2022.08.04 |
MFC - Border 속성이 Resizing이 아닌데도 계속 리사이징 될 때 (0) | 2022.08.03 |
AWS 사용자 종류 (0) | 2022.07.26 |
Apache Spark :: Windows에 설치하기 (0) | 2022.07.24 |
댓글