상세 컨텐츠

본문 제목

[Android]스레드 구현

Android 개발

by mobile 2013. 9. 18. 18:14

본문

반응형

자바언어에서 아래와 같이 2가지 방법을 사용하여 스레드를 구현한다.

- Runnable 인터페이스 구현

: java.lang 패키지의 Runnable 인터페이스를 직접 구현한다.

- 스레드 상속

: java.lang 패키지의 Thread 클래스를 상속하고 run() 메서드를 오버라이드하여 작성한다. Thread 클래스는 Object 클래스로 부터 상속 받고 Runnable 인터페이스로 구현하는 것으로 되어 있다.


Runnable 인터페이스에는 단 하나의 run()이라는 추상 메서드를 제공한다. 따라서 스레드를 상속받거나 Runnable 인터페이스를 구현하거나 동일하게 run() 이라는 메서드를 오버라이드 하여 구현해야 한다.


스레드 클래스는 아래와 같이 추가적인 메서드를 제공한다.

- static Thread currentThread()

: 현재 실행중인 스레드를 반환한다.


- static void sleep(long time);

: 매개변수로 지정한 time동안 스레드 실행을 대기한다. time 단위는 1/1000초인 ms 이다.


- void start();

: 스레드를 시작시키는 메서드다. start 메서드 호출시 run() 메서드를 실행 하게 된다.


- boolean isAlive()

: 스레드가 시작되었고 아직 끝나지 않았다면 true를 반환한다. 만약 종료되었다면 false를 반환한다.


[스레드 생명 주기]

- New : 스레드 생명주기의 시작으로 인스턴스는 만들어졌으나 아직 실행(Running)이 되지 않은 상태를 말한다.

- Runnable : start() 메서드 호출에 의해 스레드는 Runnable 상태로 이동한다.

- Running : 스케줄러는 Runnable pool 체크하고 스레드를 Running 상태로 이동시킨다. 이때 개발자가 작성한 run 메서드가 호출된다.

- Blocking : sleep() 메서드, wait() 메서드, I/O 입출력 요청, 대기 상태로 이동한다.

- Dead : 실행이 완료되면 자연스럽게 스레드는 종료된다. 이상태에서 다시 시작되는 것은 불가능 하다.


스레드는 일회용으로 한번 사용한 스레드는 재사용할 수 없다.


interrupt는 우선 SecurityManager 클래스의 checkAccess() 메서드를 호출하여 인터럽트를 요청한 스레드가 정상적인 권한을 갖고 있는지 예를들어 스레드가 같은 프로세스내에 소속되었는지를 확인한다. 만약 스레드가 정상적인 권한이 없다면, SecurityException이라는 예외사항을 발생 시킨다.


그리고 다음과 같은 스레드 상태에 따라 스레드의 종료 작업을 진행하게 된다.


- 메서드에 의한 대기 상태

: 현재 sleep() 이나 wait() 또는 join() 메서드들을 만나 대기상태에 있다면 스레드를 정상적으로 종료시키기 위하여 스레드를 깨우고 InterruptedException 이라는 예외를 발생시키면서 스레드를 종료시킨다.


- 작업대기 상태

: 스레드 작업 스케줄에 따라 대기상태에 있는 경우, 정상적으로 대기상태에서 실행상태로 될때까지 기다리게 되고 스레드가 정상적으로 실행하면 그때 종료하게된다. 이 경우는 별도 예외 사항이 발생하지 않는다.


- I/O 작업에 따른 대기 상태

: 스레드가 커널에서 파일이나 네트워크 I/O 작업이 완료 될때까지 기다리는 대기 상태를 의미한다. 이 상태에서는 우선적으로 CloseByInterruptException를 발생시켜 커널로 하여금 I/O 채널을 닫도록 요청한다. 그리고 커널에서 I/O 채널을 닫게되면, 커널은 I/O를 요청한 스레드에게 "인터럽트 요청에 의한 I/O 채널을 닫었다"는 메시지인 InterruptibleChannel을 발생시켜 스레드를 종료 시키게 된다.


[스레드 작업 예제]




//MainActivity.java

package com.example.syncthread;


import android.os.Bundle;

import android.app.Activity;

import android.content.Intent;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;


public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Button AStart = (Button) findViewById(R.id.notifyActivity);

AStart.setOnClickListener(mActivityListener);

}

private final OnClickListener mActivityListener = new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

startActivity(new Intent(MainActivity.this, NotifyingActivity.class));

}

};


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

}


// NotifyingActivity.java

package com.example.syncthread;


import android.app.Activity;

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.content.Intent;

import android.os.Bundle;

import android.view.Menu;


public class NotifyingActivity extends Activity {


private static int MOD_NOTIFICATIONS = R.layout.activity_main;

private NotificationManager mNM;

private final int[] mood = { R.drawable.stat_happy,

R.drawable.stat_neutral, R.drawable.stat_sad };

private final int[] message = { R.string.status_bar_happy_message,

R.string.status_bar_ok_message, R.string.status_bar_sad_message };


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_notifying);


mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

mThread a = new mThread();

a.start();


}


private void showNotification(int moodId, int textId) {

CharSequence text = getText(textId);

Notification notification = new Notification(moodId, text,

System.currentTimeMillis());

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,

new Intent(this, MainActivity.class), 0);

notification.setLatestEventInfo(this, getText(R.string.status_bar_mood_title), text, contentIntent);

mNM.notify(MOD_NOTIFICATIONS, notification);

}


private class mThread extends Thread {


@Override

public void run() {

// TODO Auto-generated method stub

// super.run();

for (int i = 0; i < 3; ++i) {

showNotification(mood[i], message[i]);

try {

sleep(5000);

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

}

finish();

}

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.notifying, menu);

return true;

}


@Override

protected void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

mNM.cancel(MOD_NOTIFICATIONS);

}

}




반응형

관련글 더보기

댓글 영역