will come true

[Android] Message 객체, Messenger 객체 본문

Android

[Android] Message 객체, Messenger 객체

haehyun 2022. 1. 23. 19:01
728x90

Message 객체

  • 설명과 임의의 데이터 객체를 포함한 채 Handler로 보내지는 메시지.
  • 2개의 int형 엑스트라 필드 + object형 엑스트라 필드 포함
  • 프로세스 간 통신(inter-process communication, IPC)할 때, 외부 앱과 연동하여 프로세스끼리 통신할 때 전달되는 테이버 타입.
  • 외부에서 서비스(Service)로 데이터를 전달할 때 handleMessage() 함수 매개변수로 받아지는 게 Message타입.

 

Message 클래스 주요 멤버

타입 필드 설명
int what 수신자 측에서 무엇에 대한 메시지인지(어떤 성격의 데이터인지) 식별하기 위한 사용자 지정 메시지 코드
int arg1 간단한 정수 값만을 저장할 때 사용하는 필드
int arg2 간단한 정수 값만을 저장할 때 사용하는 필드
Object obj 수신자에게 보내는 임의 객체 (=전달 데이터)
Messenger replyTo 이 메시지에 회신할 수 있는 옵션 Messenger
int sendingUid 메시지를 보낸 udi를 나타내는 옵션 필드

 

Message 객체 생성 방법 3가지

// Message 객체를 직접 생성
val msg = Message()		

// 메시지 풀에서 Message 객체 획득
val msg = Message.obtain()

// 메시지를 전송할 핸들러에서 Message 객체 획득
val handler = Handler()			// 현재 Handler() 생성자는 @Deprecated됨
val msg2 = handler.obtainMessage()

 

Messenger 객체

  • 다른 사용자가 Message를 보내는 데 사용할 수 있는 Handler에 대한 참조
  • 한 프로세스에서 Handler를 가리키는 Messenger를 만들고, 이 Messenger를 다른 프로세스에 전달함으로써 프로세스간 Message기반 통신을 구현한다.
  • bindService() 함수로 서비스를 실행할 때, Messenger 객체를 바인딩해서 사용할 수 있다.
  • 프로세스 간 통신(inter-process communication, IPC) 할 때, 외부 앱과 연동하여 프로세스끼리 통신할 때 사용한다.

 

+) 안드로이드에서 프로세스 간 통신하는 방법

  1. Messenger 객체를 사용하는 방법
  2. AIDL 파일을 사용하는 방법

 

Messenger 코드 예제 (메신저 바인딩)

액티비티와 서비스 코드에서 Messenger객체를 사용해서 데이터를 주고 받기

[MyService.kt] : 메신저 객체를 이용하는 서비스 코드

class MyService : Service() {
    lateinit var messenger: Messenger

    internal class IncomingHandler(
        context: Context,
        private val applicationContext: Context = context.applicationContext
    ) : Handler(Looper.getMainLooper()) {
        // 외부에서 서비스에 데이터를 전달할 때 자동 호출, msg : 외부에서 전달한 메시지
        override fun handleMessage(msg: Message) {
            // 전달받은 메시지 받기
            when (msg.what) {
                10 -> Toast.makeText(applicationContext, "${msg.obj}", Toast.LENGTH_SHORT)
                20 -> Toast.makeText(applicationContext, "${msg.obj}", Toast.LENGTH_SHORT)
                else -> super.handleMessage(msg)
            }
        }
    }

    override fun onBind(intent: Intent): IBinder {
        // Messenger 생성자 매개변수로 Hanlder를 구현한 객체 지정
        messenger = Messenger(IncomingHandler(this))
        // Messenger 객체의 binder 속성은 IBinder 타입, 메시지 전달하기
        return messenger.binder
    }
}

 

[MainActivity.kt] : 메신저 객체를 이용하는 액티비티 코드

class MainActivity : AppCompatActivity() {
    lateinit var messenger: Messenger

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 인텐트 생성, 서비스 실행
        val intent = Intent(this, MyService::class.java)
        bindService(intent, connection, Context.BIND_AUTO_CREATE)
        
        // 서비스에 메시지 전달
        val msg = Message()
        msg.what = 10
        msg.obj = "hello"
        messenger.send(msg)
    }

    // ServiceConnection 객체 생성
    val connection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            // Messenger(target: IBinder) 생성자, 전달받은 메시지 받기
            messenger = Messenger(service)
        }

        override fun onServiceDisconnected(name: ComponentName?) {
        }
    }
}

 

위 예제는 같은 앱에서 데이터를 주고 받는 걸로 테스트한 코드일 뿐, 외부 앱과 통신할 때는 Message객체의 obj 속성을 설정하여 주고 받을 수 없다. 프로세스 간 통신에서 주고받는 데이터는 Parcelable이나 Bundle 타입이어야 한다.

val bundle = Bundle()
bundle.putString("data1", "hello")
bundle.putInt("data2", 10)

val msg = Message()
msg.what = 10
msg.obj = bundle
messenger.send(msg)

 

Parcelable 및 Bundle 객체

  • 액티비티 간 데이터 전송에 사용. (ex: Bundle에 현재 액티비티 정보를 담아서 이벤트 함수에 전달)
  • 프로세스 간 데이터 전송에 사용. (ex: Bundle에 데이터를 담은 뒤 Message의 obj 속성으로 지정해서 전달)
  • Parcelable : 액티비티 혹은 프로세스 간에 사용자 정의 타입을 전달하기 위해서는 Parcelable인터페이스를 구현해야한다.
    ex) 학생 정보를 Student객체로 묶어서 다른 프로세스로 전달하려면 앞서 선언해둔 Student 클래스가 Parcelable 인터페이스를 구현 변경하고 Parcelable에 선언되어 있는 함수들을 Student에서 정의해야 한다.
  • Bundle : 문자열 키들을 다양한 Parcelable 값들에 매칭한 것.

*Serializable : 직렬화, 액티비티 간에 데이터를 전달할 때 데이터를 묶어서 전달하는 것.

 


728x90
Comments