개인공부용123 프로그래밍 블로그

[안드로이드 스튜디오] 쓰레드 -2- 본문

Android Studio

[안드로이드 스튜디오] 쓰레드 -2-

개인공부용123 2016. 11. 8. 23:16

쓰레드 -2-


쓰레드 Handler에관한 글: http://itmir.tistory.com/366



Handler에 관한글은 위 블로그에 잘 정리 되어있습니다.


Handler를 상속 받는 class 예제와 Runnable객체를 이용하는 예제를 간략히 설명하겠습니다.



- Handler 상 속 클 래 스 코 드 예 제 -


package org.androidtown.thread;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {

/**
* 프로그레스바
*/
ProgressBar bar;
TextView textView01;
boolean isRunning = false;

/**
* 메인 스레드의 UI에 접근하기 위한 핸들러
*/
ProgressHandler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

bar = (ProgressBar) findViewById(R.id.progress);
textView01 = (TextView) findViewById(R.id.textView01);

handler = new ProgressHandler();
}

public void onStart() {
super.onStart();
bar.setProgress(0);
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
for (int i = 0; i < 20 && isRunning; i++) {
Thread.sleep(1000);
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
}
} catch (Exception ex) {
Log.e("MainActivity", "Exception in processing message.", ex);
}
}
});

isRunning = true;
thread1.start();
}

public void onStop() {
super.onStop();

isRunning = false;
}


public class ProgressHandler extends Handler {

public void handleMessage(Message msg) { // handleMessage()에 들어있는 코드가 수행되는 위치는 메인쓰레드

bar.incrementProgressBy(5);

if (bar.getProgress() == bar.getMax()) {
textView01.setText("Done");
} else {
textView01.setText("Working ..." + bar.getProgress());
}

}

}

}


Handler를 상속받는 ProgressHandler 객체로 UI를 수정하는 코드입니다.

handler.obtainMessage()메소드를 통해서 메세지 객체를 리턴받고

handler.sendMessage()메소드를 이용해 메세지 객체를 큐에 넣을 수 있습니다.


메세지큐에 들어간 메세지는 순서대로 핸들러가 처리하게 되며 이떄 handleMessage()메소드에 정의된 기능이 수행됩니다.



- Runnable객체를 이용하는 코 드 예 제 -


package org.androidtown.thread;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;

public class SampleThreadRunnableActivity extends Activity {

ProgressBar bar;
TextView textView01;
boolean isRunning = false;
Handler handler;
ProgressRunnable runnable;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

bar = (ProgressBar) findViewById(R.id.progress);
textView01 = (TextView) findViewById(R.id.textView01);

handler = new Handler();
runnable = new ProgressRunnable();
}

public void onStart() {
super.onStart();

bar.setProgress(0);
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
for (int i = 0; i < 20 && isRunning; i++) {
Thread.sleep(1000);

handler.post(runnable);
}
} catch (Exception ex) {
Log.e("SampleThreadActivity", "Exception in processing message.", ex);
}
}
});

isRunning = true;
thread1.start();
}

public void onStop() {
super.onStop();

isRunning = false;
}


public class ProgressRunnable implements Runnable {

public void run() {

bar.incrementProgressBy(5);

if (bar.getProgress() == bar.getMax()) {
textView01.setText("Runnable Done");
} else {
textView01.setText("Runnable Working ..." + bar.getProgress());
}

}

}

}


위의 코드와 같은 기능을 수행하지만 Runnable객체를 실행하는 코드입니다.

post함수를 이용해서 Runnable객체를 전달하면 Runnable을 상속받은 클래스안에 정의 된 run()메소드 내의 코드가 메인 스레드에서 실행되면서 프로그레스바의 값을 바꿔주는 구조입니다.

이때 유의해야할점은 Runnable객체는 쓰레드의 작업 결과물로 만들어지는 데이터를 처리해야하므로 결과물을 화면에 보여주어야 하는 부분이 있을경우 new 연산자를 이용해 Runnable 인터페이스를 구현하는것이 일반적입니다.