본문 바로가기
컴퓨터 공학/Android

[ 안드로이드 프로그래밍 ] 핸들러로 메시지 전송하기 ( 예제 포함 )

by hahehohoo 2020. 4. 8.
반응형

안드로이드 프로그래밍_핸들러로 메시지 전송하기_예제포함

 

앱을 실행할 때 프로세스가 만들어지면 그 안에 메인 메서드가 함께 만들어집니다. 그리고 메세지 큐(Message Queue)를 실행합니다. 메세지 큐를 사용하면 순차적으로 코드를 수행할 수 있는데, 이렇게 메세지 큐로 메인 스레드에서 처리할 메시지를 전달하는 역할을 핸들러 클래스가 담당합니다. 또 핸들러를 이용하면 특정 메세지가 미래의 어떤 시점에 실행되도록 스케쥴링 할 수도 있습니다. 

 

핸들러의 메시지 처리 방법을 그림으로 보실까요?

크게 3가지 방법으로 나눠볼 수 있습니다. 

1 obtainMessage() 로 메세지 큐에 있는 메시지 객체를 하나 참조할 수 있습니다. 

2 메세지 객체에 필요한 정보를 넣은 후 sendMessage() 로 메세지 큐에 넣을 수 있습니다. 

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

이때 handleMessage()에 들어있는 코드가 수행되는 위치는 메인 스레드 입니다. 

 

앞에서 만들었던 프로젝트에 핸들러를 적용해보기 위해 프로젝트(SampleThread)를 복사하겠습니다. 

아래 링크에서 실습해본 예제입니다. 

 https://bite-sized-learning.tistory.com/141

 

[ 안드로이드 프로그래밍 ] 스레드 실행하기 ( 예제 포함 )

자동으로 생성되는 메인 액티비티는 하나의 프로세스에서 처리됩니다. 따라서 메인 액티비티의 버튼 클릭 이벤트를 처리하는 일 등 액티비티 내에서 처리하는 기능들은 다 같은 프로세스 안에서 실행되죠. 이렇게..

bite-sized-learning.tistory.com

SampleThread2로 프로젝트명을 바꾸고

 

 

 

 

 

 

앱 실행이 원활할 수 있도록 app 폴더의 build 폴더를 삭제하세요. 

 

이제 MainActivity.java 파일을 수정하겠습니다. 

package com.example.samplethread;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView textView;

    MainHandler mainHandler;

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

        Button button = findViewById(R.id.btnStart);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 스레드 객체 생성하고 시작하기
                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });
        mainHandler = new MainHandler();
    }

    class BackgroundThread extends Thread {
        int value = 0;

        public void run(){
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(1000);
                }catch(Exception e){ }
                value += 1;
                Log.d("Thread", "value : " + value);

                Message message = mainHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("value", value);
                message.setData(bundle);

                // 핸들러로 메세지 객체 보내기  
                mainHandler.sendMessage(message);
            }
        }
    }

    // 핸들러 안에서 전달받은 메세지 객체 처리하기   
    class MainHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            int value = bundle.getInt("value");
            textView.setText("value 값: " + value);
        }
    }
}

- Handler 클래스에는 handleMessage() 메서드가 들어 있어 이 메서드를 다시 정의하면 메시지가 메인 스레드에서 수행될 때 필요한 기능을 넣어둘 수 있습니다.

- 이렇게 정의한 핸들러는 onCreate() 메서드에서 액티비티가 초기화될 때 new 연산자를 이용해 객체로 만들어집니다. 

- 새로 만든 스레드 객체에서 수행한 작업의 결과는 핸들러 객체의 obtainMessage()로 참조하고, sendMessage()로 메세지 큐에 넣게 됩니다.

- 데이터를 전달할 때는 Message 안의 Bundle을 사용합니다. 

- Bundle 객체의 putOOO 메서드로 데이터를 넣었다가 getOOO로 데이터를 가져옵니다. (OOO는 자료형에 따라 달라집니다. )

 

앱을 실행하고 버튼을 누르면 화면에 value 값이 표시되고 계속 변하는 것을 확인할 수 있습니다. 

 

지금까지 핸들러를 통해서 메세지를 전달할 수 있는 법을 알아보았는데요. 

다음에는 좀 더 간단하고 메인스레드에서 메세지를 주고받을 수 있는 Runnable 객체에 대해서 알아봅시다. 

 

 

 

 

반응형


댓글