마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Thread 안에 Handler 선언 문제

0 추천

제가 핸들러를 쓰레드 안에 넣으려고 하는데 안되더라구요

 

예를 들어서 MainActivity가 있다고 하면 그 클래스 안에 함수를 이렇게 만들었습니다.

public void Test()
{
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            Handler cHandler = new Handler()
            {
                @Override public void handleMessage(Message msg)
                {
                    //할일을 지정. 비어놔도 오류가 뜸.
                }
            };
        }
    }).start();
}

이렇게 선언해서 Test를 호출하면 오류가 납니다.(어플이 강제종료되요)

 

왜이러는건가요? 자세하게 가르켜주셨으면 합니다. 저게 Looper랑 관련이 있는건가요?

 

할수있는 방법은 없을까요?

마피 (2,970 포인트) 님이 2013년 7월 11일 질문
마피님이 2013년 7월 11일 수정

2개의 답변

0 추천
 
채택된 답변

다음과 같은 방법을 사용하세요.

public void Test() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            Handler cHandler = new Handler(Looper.getMainLooper()) {
                @Override public void handleMessage(Message msg) {
                    // 이제 오류 안 뜸.
                	Toast.makeText(MainActivity.this, 
                	               	              "오류 안 뜸", 
               	               	               	       Toast.LENGTH_LONG).show();
                }
            };
            cHandler.sendEmptyMessage(0);
        }
    }).start();
}

또는 

public void Test() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
				@Override
				public void run() {
					Toast.makeText(MainActivity.this,
 								      "Hello World!!",
								       Toast.LENGTH_LONG).show();
				}
			});
        }
    }).start();
}

  기본 생성자를 통하여 Handler 를 생성하면 내부적으로 Looper.myLooper() 를 호출하여 생성된 Handler 가 사용할 Looper 를 가져옵니다.  하지만 질문에 들어있는 코드에서 생성된 쓰레드는 Looper 를 사용하지 않습니다. 그렇기 때문에 오류가 나는 것 입니다.

  즉 Looper 를 사용하지 않는 쓰레드에서 Handler 의 기본 생성자를 이용하여 생성할 때, 내부에서 Looper.myLooper() 메소드를 이용하여 현재 쓰레드와 관련된 루퍼를 가져옵니다. 하지만 질문자님께서 생성한 쓰레드는 Looper를 사용하는 쓰레드가 아니며, 결국 myLooper() 가 null 을 리턴하기 때문에 에러가 나는 것 입니다.

   하지만 Looper.getMainLooper() 메소드를 호출하여 반환된 값을 인자값으로 넣어주면 에러가 발생하지 않습니다.      

    Looper.getMainThread() 를 통하여 가져온 Looper는 앱의 메인 쓰레드와 관련된 Looper 입니다. 

  루퍼에 대한 설명 : http://developer.android.com/reference/android/os/Looper.html 

 

칸쵸 (1,580 포인트) 님이 2013년 7월 12일 답변
마피님이 2013년 7월 12일 채택됨
와우 감사합니다. 제가 원하는 정보가 다 들어가있네요.
0 추천
핸들러는 메서드가 아니에요..

핸들러는 클래스 최상위에 올려놓으시구요, 쓰레드 안에서 핸들러를 호출을 하셔야죠.

지금  쓰레드 안에 핸들러를 호출하는게아니라 선언을 하는거잖아요.
기초개발자 (24,060 포인트) 님이 2013년 7월 11일 답변
...