본문 바로가기

Android

안드로이드(android) 쓰레드(Thread) 개념 예제

안녕하세요
코코콩입니다.

이번엔 쓰레드에 대해 공부하고, 예제를 통해 실습해보도록 하겠습니다.


"쓰레드(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을 사용하면 좀 더 유연하게 개발을 진행할 수 있는 것이죠.


Thread_test.zip


위는 예제 소스입니다.

근데 정작 프로젝트명은 handler_test인데 쓰레드만 구현했네요.

다음 포스팅엔 handler가 추가된 내용으로 올리겠습니다.


좋은 하루 되세요