이번엔 쓰레드에 대해 공부하고, 예제를 통해 실습해보도록 하겠습니다.
"쓰레드(Thread)란 무엇인가."
: Thread는 프로그램에서 실행되는 흐름의 단위를 말한다. 일반적으로 하나의 Thread를 가지고 있지만, 환경에 따라 둘 이상의 Thread를 동시에 사용할 수 있다. 이를 멀티쓰레드(multi thread)라고 한다.
위 설명 그대로 하나의 실행단위인데요, 이를 이용해 음악을 들으며 인터넷서핑을 하는 등 동시에 여러 작업을 진행할 수 있습니다.
1. Thread의 선언
Thread() : 디폴트 생성자로 Thread객체를 생성한다. 생성된 객체는 독립적으로 실행되며 고유의 스택을 가진다.
Thread(Runnable runnable) : Runnable 인터페이스 구현객체를 생성한 후 Thread의 생성자로 잔달한다. Runnable은 Run 메소드를 가지는 간단한 인터페이스로써 Thread 대신에 run 메소드를 제공하는 역할을 한다.
2. Thread 예제
2-1)Thread 사용
package com.example.handler_test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
int mainValue = 0;
int backValue = 0;
TextView mainText;
TextView backText;
Button increaseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainText = (TextView)findViewById(R.id.mainValue);
backText = (TextView)findViewById(R.id.backValue);
increaseButton = (Button)findViewById(R.id.increase);
backThread thread = new backThread();
thread.setDaemon(true);
thread.start();
increaseButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mainValue++;
mainText.setText("MainValue : "+mainValue);
backText.setText("BackValue : "+backValue);
}
});
}
class backThread extends Thread{
public void run(){
while(true){
backValue++;
//backText.setText("BackValue : "+backValue);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
자바의 쓰레드는 기본적으로 메인쓰레드와 동등한 자격을 가지며, 모든 쓰레드가 종료되어야 비로소 프로그램이 종료됩니다. 데몬쓰레드는 메인쓰레드가 종료될 때 같이 종료되는 쓰레드이며 backThread는 무한루프를 돌기 때문에 기본옵션으로 생성하면 절대 죽지않는 무적의 쓰레드가 된다나 뭐라나... 그래서 setDaemon(true)를 해주어 메인이 종료될 때 같이 사망하도록 설정했습니다.
자 그럼 위 앱을 실행시켜보겠습니다.
증가버튼을 클릭하니 backValue는 쓰레드로 인해 14가 되었고 mainValue는 버튼클릭으로 1이 되었습니다.
그렇다면 번거롭게 버튼이벤트에 setText를 통해 값을 업데이트하지 않고 쓰레드가 돌면서 1초마다 자동으로 값을 업데이트해주면 어떨까요?
thread안에 주석처리된 backText.setText가 보이시나요?
이 부분의 주석을 풀고 앱을 실행해보겠습니다.
쓰레드님이 사망하였습니다. ㅠㅠㅠㅠ
왜냐면 UI는 메인쓰레드에서만 변경이 가능하거든요....
백그라운드 쓰레드는 내부적인 연산만 해야하며, 다른 쓰레드 소속의 UI를 건드릴수 없습니다. 따라서... 핸들러를 사용해야하나 이건 다음 포스팅때...
자 이번엔 Runnable을 사용한 예제를 확인해보겠습니다.
2-2) Runnable 사용
package com.example.handler_test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
int mainValue = 0;
int backValue = 0;
TextView mainText;
TextView backText;
Button increaseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainText = (TextView)findViewById(R.id.mainValue);
backText = (TextView)findViewById(R.id.backValue);
increaseButton = (Button)findViewById(R.id.increase);
BackRunnable runnable = new BackRunnable();
Thread thread = new Thread(runnable);
thread.setDaemon(true);
thread.start();
increaseButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mainValue++;
mainText.setText("MainValue : "+mainValue);
backText.setText("BackValue : "+backValue);
}
});
}
class BackRunnable implements Runnable{
public void run(){
while(true){
backValue++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
onCreate에서 BackRunnable 타입의 runnable 객체를 생성한 후, Thread의 생성자에 전달했습니다.
2-1과 같이 Thread를 바로 사용하면 되는데 굳이 Runnable객체를 만들어 사용해야하나 생각하실 수 있으나, 자바는 다중상속을 지원하지 않기 때문에 Thread를 상속받아 사용하면 Thread 이외엔 상속을 받지 못하니 코드의 재사용성에 문제가 있겠습니다.
따라서 Runnable을 사용하면 좀 더 유연하게 개발을 진행할 수 있는 것이죠.
위는 예제 소스입니다.
근데 정작 프로젝트명은 handler_test인데 쓰레드만 구현했네요.
다음 포스팅엔 handler가 추가된 내용으로 올리겠습니다.
좋은 하루 되세요
'Android' 카테고리의 다른 글
| 안드로이드(android) 핸들러(Handler) 예제2 (2) | 2016.05.27 |
|---|---|
| 안드로이드(android) 핸들러(Handler) 개념 & 예제 (0) | 2016.05.26 |
| Android Manifest의 launchMode (1) | 2016.05.19 |
| 서버와 로컬 파일 사이즈 비교하기 (0) | 2015.11.13 |
| 블루스택, 윈드로이, 지니모션 구분하기 (0) | 2015.09.04 |
Thread_test.zip