Android

( 스크랩 ) 안드로이드 핸들러

Machine_웅 2019. 1. 8. 18:46
728x90
반응형

저번 포스트에서 핸들러에 대해 간단히 설명하였습니다. 이번 포스트에서는 핸들러를 구현하는 방법에 대해 정리합니다.

 

 

핸들러를 구현하기 위해 필요한 클래스 - Handler

안드로이드는 핸들러를 구현할 수 있도록 Handler라는 베이스 클래스를 제공합니다. 프로그래머들은 그것을 상속받는 자식 클래스를 정의하여 핸들러를 구현할 수 있습니다.

 

 

핸들러 구현 위치

구현할 핸들러 클래스의 위치를 프로그래머가 결정할 수 있습니다. 가능한 위치는 3가지입니다.


1. 메소드 내 (이 경우 핸들러는 익명 클래스로 구현됩니다.)

2. 액티비티 등과 같이 특정 클래스의 내부

3. 별도의 자바 파일


만약 핸들러의 할 일이 액티비티의 뷰들을 갱신이라면, 액티비티 클래스의 내부가 적절합니다.

 

 

핸들러를 구현하는 과정

1. 핸들러가 받을 메시지들의 종류를 결정하세요. 자식 핸들러 클래스를 어디에 구현할지 결정하세요. 여기에서는 액티비티 클래스의 내부라고 가정하겠습니다.

 

2. 메시지들의 종류가 무엇인지 식별하세요. 그 후 이들을 나타내는 정수형 상수들을 정의하세요. 이러한 상수들을 메시지 코드(message code)라고 부릅니다. 핸들러가 특정 클래스 내에서만(예: 액티비티) 사용된다면, 그 클래스 내에 메시지 코드들을 정의하시는 것이 좋습니다. 아래 코드는 날, 월, 년이 바뀔 때 발생하는 메시지들을 의미합니다.

 

public class AddingHandlerActivity extends Activity {
   
    //----------------------------------------------------------
    // Message Codes
   
    private static final int MSG_DAY_CHANGED = 1;
    private static final int MSG_MONTH_CHANGED = 2;
    private static final int MSG_YEAR_CHANGED = 3;

    
    // ...

}

 

3. 자식 핸들러 클래스를 정의하세요.

 

public class AddingHandlerActivity extends Activity {
   
    //----------------------------------------------------------
    // Message Codes
   
    private static final int MSG_DAY_CHANGED = 1;
    private static final int MSG_MONTH_CHANGED = 2;
    private static final int MSG_YEAR_CHANGED = 3;

   
    // ...
    
    private class DateHandler extends Handler
    {
       
    }
}

 

4. 자식 핸들러 클래스의 handleMessage 메소드를 정의하세요. 이 메소드에서 핸들러는 자신이 받은 메시지를 처리합니다.

 

public class AddingHandlerActivity extends Activity {
   
    //----------------------------------------------------------
    // Message Codes
   
    private static final int MSG_DAY_CHANGED = 1;
    private static final int MSG_MONTH_CHANGED = 2;
    private static final int MSG_YEAR_CHANGED = 3;

   
    // ...

    
    private class DateHandler extends Handler
    {
        public void handleMessage(Message msg)
        {
           
        }
    }
}


5. 메시지를 처리하기 전에 어떤 메시지를 받았는지 구별을 할 수 있어야지요? 이를 위해 handleMessage 메소드에 메시지의 종류를 구별하는 조건문을 작성하세요. 메시지의 종류는 여러 개가 될 수 있으므로 switch 문이 적절합니다. msg 파라메터의 what 필드를 통해 어떤 메시지를 받았는지 구별할 수 있습니다. 2에서 세 가지 메시지들을 정의하였죠. 이들을 적용한 코드는 아래와 같습니다.

 

private class DateHandler extends Handler
{
    public void handleMessage(Message msg)
    {
        switch (msg.what)
        {
            case MSG_DAY_CHANGED:
                // 메시지를 처리할 코드들을 여기에 작성하세요.
                break;

            case MSG_MONTH_CHANGED:
                // 메시지를 처리할 코드들을 여기에 작성하세요.
                break;

            case MSG_YEAR_CHANGED:
                // 메시지를 처리할 코드들을 여기에 작성하세요.
                break;

            default:    // 정의되지 않은 메시지들의 경우 여기로 분기

                break;
        }
    }
}

 

6. handleMessage 메소드의 switch 문 내에 메시지를 처리하는 코드를 작성하세요. 아래 코드의 경우 단순히 날, 월, 연이 바뀜을 토스트로 알립니다. 토스트를 만들기 위해 외부의 액티비티 클래스에 자신을 Context 데이터형으로 가리키는 필드를 추가하였습니다.

 

public class AddingHandlerActivity extends Activity {
   
    //----------------------------------------------------------
    // Message Codes
   
    private static final int MSG_DAY_CHANGED = 1;
    private static final int MSG_MONTH_CHANGED = 2;
    private static final int MSG_YEAR_CHANGED = 3;
   
    //----------------------------------------------------------
    // Fields
   
    private Context thisActivity = (Context)this;

   
    // ...

    
    private class DateHandler extends Handler
    {
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case MSG_DAY_CHANGED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Day changed.", Toast.LENGTH_SHORT).show();
                    break;


                case MSG_MONTH_CHANGED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Month changed.", Toast.LENGTH_SHORT).show();
                    break;


                case MSG_YEAR_CHANGED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Year changed.", Toast.LENGTH_SHORT).show();
                    break;


                default:

                    Toast.makeText(thisActivity, "Undefined message received.", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}

 

7. 핸들러에 메시지를 보내는 코드를 작성하세요. 과정은 다음과 같습니다.


(1) 메시지 객체를 생성하세요. new 연산자를 사용하는 것보다는 Handler 클래스의 obtainMessage 메소드들 중 하나를 호출하세요. 이들은 안드로이드의 메시지 풀로부터 메시지 객체를 리턴합니다. 풀로부터 받은 메시지를 사용할 것을 권합니다. 이 메소드들의 프로토타입들은 다음과 같습니다.

 

  • Message obtainMessage()
  • Message obtainMessage(int what)
  • Message obtainMessage(int what, Object obj)
  • Message obtainMessage(int what, int arg1, int arg2)
  • Message obtainMessage(int what, int arg1, int arg2, Object obj)

 

파라메터들의 의미는 다음과 같습니다.

 

데이터형

파라메터 이름

의미

int

what

메시지 객체의 메시지 코드입니다. 핸들러가 메시지의 종류를 구별하기 위해서는 what의 값을 지정해 주셔야 합니다.

int

arg1

메시지를 처리할 핸들러에 전달할 정수 데이터가 있으면, arg1에 값을 대입하세요.

int

arg2

메시지를 처리할 핸들러에 전달할 정수 데이터가 있으면, arg2에 값을 대입하세요.

Object

obj

메시지를 처리할 핸들러에 전달할 객체가 있으면, obj에 객체를 대입하세요. 모든 객체들은 Object 클래스를 상속 받기 때문에 모든 종류의 객체들이 가능합니다.

 

날이 지났음을 알리기 위한 메시지 코드 MSG_DAY_PASSED를 갖는 메시지 객체를 만들려면, 다음과 같이 코드를 작성하실 수 있습니다. 만약에 핸들러에게 전달할 자료나 객체가 있다면, 파라메터 arg1, arg2, obj를 추가하시면 되겠습니다.

DateHandler dateHandler = new DateHandler();

Message msg = dateHandler.obtainMessage(MSG_DAY_PASSED);


(2) 메시지를 보내는 메소드를 호출하세요. 메시지를 보내는 메소드들의 종류들은 다음과 같습니다.

 

메시지를 어떻게 보내고 싶은가?

메시지를 보내는 메소드들의 프로토타입

메시지를 보냅니다.

boolean sendMessage(Message msg)

지정된 시간에 메시지를 보냅니다.

(예: 7월 7일 7시 7분에 메시지를 보냅니다.)

boolean sendMessageAtTime(

    Message msg,

    long uptimeMillis)

지정된 시간만큼 지연 후 메시지를 보냅니다.

(예: 3초 후 메시지를 보냅니다.)

boolean sendMessageDelayed(

    Message msg,

    long delayMillis)

메시지를 빨리 보냅니다.

boolean sendMessageAtFrontOfQueue(Message msg)

 

(1)의 예에서 정의된 메시지를 핸들러에게 보내는 코드를 작성해 보겠습니다. 앞에서 정의했던 메시지 객체(msg. 메소드의 msg 파라메터와 이름이 같네요.)를 메소드의 msg 파라메터로 대입해 주시면 되겠습니다.

 

DateHandler dateHandler = new DateHandler();

Message msg = dateHandler.obtainMessage(MSG_DAY_PASSED);

dateHandler.sendMessage(msg);

 

 

지금까지 보여드린 과정들을 조합한 예를 보여드리겠습니다. 이 예는 액티비티가 시작될 때 MSG_DAY_PASSED 메시지를 핸들러에 보내는 프로그램입니다. 그 결과, "Day passed."라는 문구가 토스트로 보입니다. 프로젝트 파일을 첨부로 올리오니 참고하시기 바랍니다.

package me.blog.netrance.android.example.addinghandler;

 

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

 

public class AddingHandlerActivity extends Activity {
   
    //----------------------------------------------------------
    // Message Codes
   
    private static final int MSG_DAY_PASSED = 1;
    private static final int MSG_MONTH_PASSED = 2;
    private static final int MSG_YEAR_PASSED = 3;
   
    //----------------------------------------------------------
    // Fields
   
    private Context thisActivity = (Context)this;
    private DateHandler dateHandler = new DateHandler();
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        //------------------------------------------------------
       
        Message msg = dateHandler.obtainMessage(MSG_DAY_PASSED);
        dateHandler.sendMessage(msg);
    }
   
    private class DateHandler extends Handler
    {
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case MSG_DAY_PASSED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Day Passed.", Toast.LENGTH_SHORT).show();
                    break;
                case MSG_MONTH_PASSED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Month Passed.", Toast.LENGTH_SHORT).show();
                    break;
                case MSG_YEAR_PASSED:
                    // 메시지를 처리할 코드들을 여기에 작성하세요.
                    Toast.makeText(thisActivity, "Year Passed.", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(thisActivity, "Undefined message received.", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}

 

 

마치며...

지금까지 핸들러를 구현하는 방법에 대해 알아보았습니다. 다음에는 스레드가 핸들러에 메시지를 보내는 방법을 통해 좀 더 자세히 공부해 보도록 하겠습니다.

728x90
반응형

'Android' 카테고리의 다른 글

(스크랩) 안드로이드 앱 종료시키기  (1) 2019.04.20
(스크랩 )Glide 옵션들  (0) 2019.01.28
안드로이드 php Json  (1) 2018.11.14
안드로이드 SMS 문자메세지 보내기  (0) 2018.10.25
안드로이드 MediaController  (0) 2018.08.04