본문 바로가기

Android/Handler & Thread

Android Thread & Handler example

Android 기반에서 User Thread의 사용은 표준 자바에 비해서 기능의 제한이 따른다

제한된 실행환경에서 필수적인 폰의 기능을 보호하면서 자원을 절약하기 위해서는 그 만큼 시스템 차원의 통제가 필요할 것이다

안드로이드의 유저 쓰레드는 메인 쓰레드에 비해서 UI 갱신을 할 수 없도록 되어 있다.

즉, 메인 쓰레드에서만 화면을 갱신할 수 있도록 제한하고 있으며 유저 쓰레드에서 산출된 데이터를 이용하여 화면을 갱신하고 한다면 유저 쓰레드에서는 안되고 메인 쓰레드의 도움을 받아야 한다. 유저 쓰레드가 메인 쓰레드에게 메시지를 보내면 메인 쓰레드에서는 메시지를 수신하는 메소드를 호출하고 그 안에서 화면을 갱신하면 된다.

아래의 코드는 유저 쓰레드에서 메시지를 전송하고 메인 쓰레드에서 메시지를 수신하여 화면을 갱신하는 예이다

메시지 전달과 수신을 위해 Handler 클래스를 사용해야 한다


package com.example.androidtest;


import android.os.*;

import android.util.Log;

import android.view.*;

import android.widget.*;

import android.app.*;

import android.content.Context;


public class MainActivity extends Activity {


TextView tv;

int cnt;

// 메인 쓰레드와 자동으로 연결되는 메시지 핸들러

Handler handler = new MainHandler();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.textView1);

Button btn = (Button) findViewById(R.id.button1);

btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

new Thread() {

public void run() {

cnt = 0;

for(int i=0;i<10;i++)

{

try {

Thread.sleep(1000);

cnt++;

/* 아래처럼 유저 쓰레드 내에서 UI 갱신은 안되며

화면 갱신은 메인 쓰레드 내에서만 가능하다

*/

//tv.setText(cnt++ + "");

/*유저 쓰레드에서 화면갱신이 필요한 경우에는 아래처럼

* 핸들러를 통해 메인 쓰레드의 메시지 큐에 메시지를 보내면

* 메인 쓰레드에서는 Looper를 경유하여 handleMessage()를 

* 실행하므로 메인 쓰레드 영역인 handleMessage()내에서 화면을 갱신할 수 있다.

* */

Message msg = handler.obtainMessage();

handler.sendMessage(msg);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}.start();

}

});

}


/* 아래의 Handler 클래스는 메인 쓰레드 영역에 선언하고 메인 쓰레드 안에서 인스턴스를

* 생성하므로 메인 쓰레드의 메시지 큐와 자동으로 연결되어 메시지를 가져오는 핸들러이다

* 메인 쓰레드 내에서 실행되는 Looper 가 메시지 큐를 감시하다가 메시지가

* 발견되면 Handler 클래스의 handleMessage()를 호출한다.

* 그러므로 handleMessage()는 메인 쓰레드의 일부분으로 실행되므로 이 메소드 내에서

* 화면을 갱신하는 코드를 실행하여 화면을 갱신하는데 문제가 없다

*/

class MainHandler extends Handler

{

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

Log.i("핸들러 작동", "메시지 도착");

tv.setText(cnt+"");

super.handleMessage(msg);

}

}

}