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

handlerThread 관련하여 소스코드상에서 질문드립니다.(간단한 예제임)

0 추천
//아래의 소스 코드를 실행하면 뷰는 UI쓰레드에서 업데이트를 하라는 메세지가 나오며 앱이 종료됩니다. 
//Log.d(TAG, Thread.currentThread().getName()); HandlerThread.Handler가 찍히면서 현재 실행중인
//쓰레드가 main이 아닌 HandlerThread.Handler라는걸 알 수 있습니다.

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


    final HandlerThread hThread = new HandlerThread("HandlerThread.Handler");
    hThread.start();
    btnTest = (Button) findViewById(R.id.btn_test);

    btnTest.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            Handler h = new Handler(hThread.getLooper())
            {
                public void handleMessage(Message msg)
                {
                    Log.d(TAG, Thread.currentThread().getName());
                    Log.d(TAG, Thread.currentThread().getThreadGroup().getName());

                    btnTest.setText("test");
                }
            };
            h.sendMessage(new Message());
        }
    });
}
//아래의 소스를 실행하면 동작합니다. 
// Log.d(TAG, Thread.currentThread().getName()); 가 HandlerThread.Handler로 찍혔는데도 동작을
//하는데요. mainThread가 아님에도 뷰가 업데이트 되는 이유는 무엇일까요?

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


    final HandlerThread hThread = new HandlerThread("HandlerThread.Handler");
    hThread.start();
    btnTest = (Button) findViewById(R.id.btn_test);

    Handler h = new Handler(hThread.getLooper())
    {
        public void handleMessage(Message msg)
        {
            Log.d(TAG, Thread.currentThread().getName());
            Log.d(TAG, Thread.currentThread().getThreadGroup().getName());

            btnTest.setText("test");
        }
    };
    h.sendMessage(new Message());
}
 
lanevo (590 포인트) 님이 2015년 8월 20일 질문
lanevo님이 2015년 8월 20일 수정

2개의 답변

0 추천
aucd29 (218,390 포인트) 님이 2015년 8월 20일 답변
아 혹시 오래걸리는 작업이 아니면 uiThread가 아니어도 뷰가 업데이트 되나요?
그런 의미로 위 링크를 걸어주신건지 궁금합니다.
0 추천

자답 입니다.

반복문에서 업데이트 하면 죽네요. 죽어야 정상이라고 생각했는데 안죽어서 희한하다고 생각했는데

반복문에서 업데이트 하니 i == 1에서 ui 쓰레드에서 Only the original thread that created a view hierarchy can touch its views. 문구가 나왔습니다. getMainLooper()에 연결하면 당연히 안죽습니다. onClickListener에서는 반복문 안해도 한번에 죽네요. 아시는 분 답변부탁드립니다.

Handler h = new Handler(getMainLooper())

public void handleMessage(Message msg)
{
    Log.d(TAG, Thread.currentThread().getName());
    Log.d(TAG, Thread.currentThread().getThreadGroup().getName());

    int i = 0;
    while (i < 10)
    {
        Log.d(TAG, "i : " + i);
        btnTest.setText("test" + i);
        i++;

        try
        {
            Thread.sleep(2000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
lanevo (590 포인트) 님이 2015년 8월 20일 답변
handleMessage 에서 for 문을 돌게 아니고
for 문으로 handler 에 메시지를 10개를 보내는 식이면 잘 처리 됩니다.
제가 궁금했던 거는 mainThread 연결되어있는 handler에 메세지 보내서 ui를 업데이트하는게 아니고 handler와 handlerThread하나 만들어서 handler에handlerThread의 looper를 연결하여 현재 동작하는 쓰레드가 mainThread가 아닌 handlerThread인데 어째서 뷰가 업데이트 되었는가 였습니다. 제가 올려놓은 코드를 한번 돌려보셨다면 의미가 파악되셨을거 같은데 아쉽네요
...