2010/05/02
[Android Dev.] Thread 사용하기
Android 의 Thread 를 사용해 보았다. 이미 올린 글에서 Progress Dialog 를 제어 하면서도 사용을 해 보았지만 개념이 쉽게 와 닿지 않아 다시 공부해 보았다.
Android 의 Thread 는 Thread 껍데기를 담당하는 Thread 객체와 실제 실행되는 부분을 담당하는 Runnable 객체로 구성이 되는데 Android 에서는 Multi Thread 를 지원을 하지만 여러 Thread 에서 메인 UI를 제어하지 않고 하나의 Thread 혹은 Handler 라는 객체에서 담당을 하도록 한다.
Thead의 생성의 Thread 객체를 생성할 때, Runnable 객체를 넘겨주어 생성을 한다.
public Thread (Runnable runnable)
Thread 의 테스트를 위해 아래와 같은 메인 UI를 작성하였다.
Progress bar 와 쓰레드 동작시킬 버튼이다.
아래 소스는 아주 간단하게 버튼이 눌렸을 때 Thread를 생성하여 Progress bar를 진행시키는 코드 이다.
위의 소스 중에 Toast 메세지를 출력하는 부분이 있는데 이 부분의 주석을 해제하고 실행하면 아래와 같은 예외가 발생을 하는데 왜 그런지는 모르겠고 Backgroud Thread 에서 메인 UI를 제어하려고 시도해서 인 것을 생각이 된다.
Handler 를 이용한 Message Queueing 방식
다음은 Handler 를 이용한 message queueing 방식을 이용하는 Thread 를 생성하여 보았다. Thread 에서 Handler 에게 message 를 보내어 Handler 가 받은 message 를 처리하며 UI 작업을 하도록 하는 것이다.
Handler 에게로 Message를 보내기 위해서는 Handler 에서 obtainMessage 함수를 이용해 Message 객체를 받아와서 필요한 정보를 담아 다시 Handler 에게 보내는 것이다. Handler 는 받은 메세지를 순서대로 handleMessage 함수를 통해 처리한다.
이 때, Handler 에게 Message 를 보내는 방법이 여러가지가 있다.
Foreground Thread에 post 메세지에 의한 방법
또 다른 방법은 UI 핸들링을 하는 Foreground Thread 를 두고 Background Thread 에서 post 함수를 이용하여 처리하는 방식이다.
위의 두가지 Thread 운영 방식은 유사하게 동작을 하며 버튼이 눌려지면 Thread 를 동작하여 Progress 바의 진행을 시킨다.
Android 의 Thread 는 Thread 껍데기를 담당하는 Thread 객체와 실제 실행되는 부분을 담당하는 Runnable 객체로 구성이 되는데 Android 에서는 Multi Thread 를 지원을 하지만 여러 Thread 에서 메인 UI를 제어하지 않고 하나의 Thread 혹은 Handler 라는 객체에서 담당을 하도록 한다.
Thead의 생성의 Thread 객체를 생성할 때, Runnable 객체를 넘겨주어 생성을 한다.
public Thread (Runnable runnable)
Thread 의 테스트를 위해 아래와 같은 메인 UI를 작성하였다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ProgressBar
android:id="@+id/ProgressBar01"
style="?android:attr/progressBarStyleHorizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
<Button
android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</LinearLayout>
Progress bar 와 쓰레드 동작시킬 버튼이다.
아래 소스는 아주 간단하게 버튼이 눌렸을 때 Thread를 생성하여 Progress bar를 진행시키는 코드 이다.
ProgressBar progress01;
Button btn01;
progress01 = (ProgressBar)findViewById( R.id.ProgressBar01 );
btn01 = (Button)findViewById( R.id.Button01 );
btn01.setOnClickListener( this );
public void onClick( View v )
{
if ( v == btn01 )
{
new Thread(new Runnable()
{
public void run()
{
progress01.setProgress( 0 );
progress01.setMax( 100 );
for ( int i = 0; i <= 100; ++i )
{
progress01.setProgress( i );
SystemClock.sleep(100);
}
//Toast.makeText(MyThread.this, "Thread Finished", Toast.LENGTH_SHORT).show();
}
}
).start();
}
}
위의 소스 중에 Toast 메세지를 출력하는 부분이 있는데 이 부분의 주석을 해제하고 실행하면 아래와 같은 예외가 발생을 하는데 왜 그런지는 모르겠고 Backgroud Thread 에서 메인 UI를 제어하려고 시도해서 인 것을 생각이 된다.
Handler 를 이용한 Message Queueing 방식
다음은 Handler 를 이용한 message queueing 방식을 이용하는 Thread 를 생성하여 보았다. Thread 에서 Handler 에게 message 를 보내어 Handler 가 받은 message 를 처리하며 UI 작업을 하도록 하는 것이다.
Handler myHandler = new Handler()
{
public void handleMessage( Message msg )
{
if ( msg.what == -1 )
{
progress01.setProgress( 0 );
progress01.setMax( 100 );
}
else if ( msg.what == -100 )
{
Log.i( "INFO", "Finish Thread!!!" );
Toast.makeText(MyThread.this, "Finish Thread!!!", Toast.LENGTH_SHORT).show();
}
else
{
progress01.setProgress( msg.what );
}
}
};
public void onClick( View v )
{
if ( v == btn01 )
{
new Thread(new Runnable()
{
public void run()
{
Message msg = myHandler.obtainMessage();
msg.what = -1;
myHandler.sendMessage( msg );
for ( int i = 0; i <= 100; ++i )
{
msg = myHandler.obtainMessage();
msg.what = i;
myHandler.sendMessage( msg );
SystemClock.sleep(100);
}
msg = myHandler.obtainMessage();
msg.what = -100;
myHandler.sendMessage( msg );
}
}
).start();
}
}
Handler 에게로 Message를 보내기 위해서는 Handler 에서 obtainMessage 함수를 이용해 Message 객체를 받아와서 필요한 정보를 담아 다시 Handler 에게 보내는 것이다. Handler 는 받은 메세지를 순서대로 handleMessage 함수를 통해 처리한다.
이 때, Handler 에게 Message 를 보내는 방법이 여러가지가 있다.
- final boolean sendMessage(Message msg)
Message 를 Handler 의 Message Queue 에 맨 마지막에 추가한다. - final boolean sendMessageAtFrontOfQueue(Message msg)
Message 를 Handler 의 Message Queue 의 맨 앞에 추가한다. - boolean sendMessageAtTime(Message msg, long uptimeMillis)
Message 를 특정 시각(장비 가동후 지난 시간)이 되면 Queue에 추가한다. - final boolean sendMessageDelayed(Message msg, long delayMillis)
Message 를 특정 시간이 지난 후에 Queue에 추가한다.
Foreground Thread에 post 메세지에 의한 방법
또 다른 방법은 UI 핸들링을 하는 Foreground Thread 를 두고 Background Thread 에서 post 함수를 이용하여 처리하는 방식이다.
Handler myHandler = new Handler();
private Runnable fgTask = new Runnable()
{
@Override
public void run()
{
int nCur = progress01.getProgress();
if ( nCur != progress01.getMax() )
{
nCur++;
progress01.setProgress( nCur );
}
else
{
Toast.makeText( MyThread.this, "Finish Thread", Toast.LENGTH_SHORT).show();
}
}
};
public void onClick( View v )
{
if ( v == btn01 )
{
new Thread(new Runnable()
{
public void run()
{
for ( int i = 0; i <= 100; ++i )
{
myHandler.post( fgTask );
SystemClock.sleep(100);
}
}
}
).start();
}
}
위의 두가지 Thread 운영 방식은 유사하게 동작을 하며 버튼이 눌려지면 Thread 를 동작하여 Progress 바의 진행을 시킨다.
Labels:
Android
,
Android Development
,
Message Queueing
,
Progress Bar
,
runnable
,
thread
,
TistoryOldPost
,
안드로이드
,
안드로이드 개발
Subscribe to:
Post Comments
(
Atom
)
No comments :
Post a Comment