본문 바로가기
개발 관련 이야기

Thread 내에서 Toast 띄우기

by 꿈틀쓰 2022. 8. 2.

문제점

스레드가 돌다가 특정 조건을 만족하면 토스트를 띄우게 하려고 했으나, 다음과 같은 예외가 발생한다.

 

Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

 

이유

UI에 영향을 주는 스레드는 메인스레드가 담당한다. 

그 이유를 찾아보고 이해한 바는 다음과 같다.

 

그림 1. TextView에 접근하는 하나 이상의 Thread

만약의 (그림 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로 적용하였다.

댓글