개발 창고/Android

[Android] Thread 사용하기

로이제로 2020. 7. 23. 17:38
반응형

안드로이드 개발을 하다 보면 가끔 단일 스레드에서 작업이 진행이 어려운 경우가 발생합니다.

이런 경우 새로운 스레드를 만들어 run 해야 하는 경우가 더러 있는데요

이번에는 스레드를 쓰는 간단한 예제를 적어볼까합니다.

 

아래의 소스는  5초간 스레드에서 메시지를 Activity로 전송하고 Interrupt 발생으로 Thread를 멈추는 Activity입니다.

public class ThreadActivity extends AppCompatActivity {
    // 스레드에서 전송한 Message를 처리할 handler
    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler(){
        public void handleMessage(Message msg){
            Log.d("MSG_TAG", msg.arg1 + "," + msg.arg2 + "," + msg.obj);
        }
    };

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

        CustomThread mThread = new CustomThread();    // 커스텀 스레드 선언
        mThread.start();                              // 커스텀 스레드 run

        // 5초 후 Interrupt 발생하도록 작업
        try{
            Thread.sleep(5000);

            mThread.interrupt();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    // 사용자 저으이 스레드
    private class CustomThread extends Thread {
        @Override
        public void run(){
            int i = 0;

            while(!isInterrupted()) {
                i++;
                try{
                    // 스레드에서 호출한 Activity로 메시지 전달
                    Message message = handler.obtainMessage();
                    message.arg1 = 0;
                    message.arg2 = i;
                    message.obj = "RUNNING!!";
                    handler.sendMessage(message);
                    
                    // 1초간 멈춤
                    sleep(1000);
                }catch(InterruptedException e){
                    Message message = handler.obtainMessage();
                    message.arg1 = 0;
                    message.arg2 = i;
                    message.obj = "INTERRUPTED!!";
                    handler.sendMessage(message);

                    // 현재 스레드를 Interrupt
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

Point 1. private 변수인  handler는 Thread에서 Activity로 메시지를 전송할 수 있도록 선언한 Handler로써, 만약 TextView나 ImageView등에 값을 변경하고 싶을 경우, Thread내에서 직접 수정은 자원문제로 불가능하기 때문에 해당 handler에서 처리가 되어야 합니다. (주로 스레드를 쓰다 보면 자주 있는 문제입니다.)

 

Point 2. onCreate에서는 단순히 Thread 생성 후 5초 뒤에 해당 스레드에 interrupt를 호출하도록 처리했습니다. 일반적으로 Thread에서 for문 등으로 반복 처리해도 되지만, while이나 for문 내에서 처리 시간이 길어지면, 해당 플래그를 인식하는 데까지 시간이 오래 걸리기 때문에 interrupt를 활용하면 즉각적으로 반응을 이끌어 낼 수 있는 장점이 있습니다.

 

Point 3. Thread에서 sleep을 사용 시에 유의하셔야 할 점은, Thread.sleep로 하게 되면, 새로운 스레드에서 작동하기 때문에 mThread.interrupt() 호출 시에 해당 sleep이 interrupt가 되지 않는다는 점입니다. (개발하다가 이거 때문에 몇 시간 찾느라 고생했네요)

 

LogCat에 호출된 Message 결과

반응형