카테고리 없음

브로드캐스트 리시버 Broadcast Receiver

hegunhee 2021. 12. 22. 15:49

지난 글중에 액티비티 생명주기에대해 정리한것이 있지만 책을 보고 복습 겸 다시한번 정리하겠습니다.

위 글은 Do it! 깡쌤의 안드로이드 앱 프로그래밍 with 코틀린(강성윤 지음)을 보고 정리한 내용입니다.

브로드캐스트 리시버는 흔히 이벤트 모델로 실행되는 컴포넌트라고 정의합니다. 여기서 이벤트란 액티비티를 다룰 때 사용한 이벤트가 아니라 부팅이 완료되는 것과 같은 시스템의 특정한 상황을 의미합니다.

시스템에 어떤 이벤트가 발생하면 브로드캐스트 리시버를 실행해 앱이 해당 상황에 맞게 동작하도록 할 수 있습니다.

 

이것도 액티비티처럼 안드로이드의 컴포넌트이므로 인텐트를 시스템에 전달함으로써 실행합니다.

 

브로드캐스트 리시버 만들기


브로드캐스트 리시버를 만들려면 BroadCastReceiver를 상속받는 클래스를 선언해야 합니다. 브로드캐스트 리시버의 생명주기 함수는 onReceive() 하나뿐입니다. 어디선가 이 리시버를 실행하려고 인텐트를 실행하면 onReceive() 함수가 자동으로 호출됩니다. 그리고 자신을 호출한 인텐트 객체를 매개변수로 전달받습니다.

class MyReceiver : BroadcastReceiver() {
	override fun onReceive(context : Context, intent : Intent){
    }
}

onReceive() 함수는 실행한 후 10초 이내에 완료할 것을 권장하므로 오래 걸리는 작업을 담기에는 부적절합니다.

onReceive() 함수가 실행을 마치면 브로드캐스트 리시버 객체는 소멸합니다.

 

브로드캐스트 리시버도 컴포넌트이므로 매니페스트 파일에 등록합니다. 브로드캐스트 리시버를 등록하는 태그는 

<receiver>이며 필수 속성은 클래스를 지정하는 name입니다. 브로드캐스트 리시버를 명시적으로 실행하려면 클래스명만 등록하고. 암시적으로 실행하려면 <intent-filter>를 선언해 줘야 합니다.

(안드로이드 스튜디오에서 create -> broadcastReceiver로 생성하면 매니페스트에 자동으로 등록되지만 한번 더 확인해줘야됩니다)

<receiver
	android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true"></receiver>

동적 등록과 해제


안드로이드 컴포넌트는 매니페스트에 등록해야 시스템에서 인지하고 어디선가 인텐트가 발생할 때 컴포넌트를 실행해 줍니다. 이러한 동작 방식은 브로드캐스트 리시버에서도 마찬가지지만 매니페스토에 등록하지 않고 코드에서 필요한 순간에 동적으로 등록할 수도 있습니다.

다음 코드는 액티비티나 서비스 컴포넌트에서 작성한 코드입니다.

receiver = object : BroadcastReceiver() {
	override fun onReceive(context: Context?, intent : Intent?){
    }
}

브로드캐스트 리시버 객체는 액티비티나 서비스에서 생성할 수 있습니다. 그리고 필요한 순간에 다음처럼 registerReceiver() 라는 함수를 이용해 시스템에 등록합니다.

val filter = IntentFilter("ACTION_RECEIVER")
registerReceiver(receiver,filter)

이처럼 브로드캐스트 리시버를 코드에서 등록하면 매니페스트에 <receiver> 태그로 등록하지 않아도 시스템에서 리시버의 존재를 인지합니다.

registerReceiver() 함수로 등록한 리시버는 사용한 후 필요 없으면 해제해 줘야 합니다. 이때 unregisterReceiver() 함수를 이용합니다.

unregisterReceiver(receiver)

브로드캐스트 리시버 실행하기


브로드캐스트 리시버를 실행하려면 인텐트가 필요합니다. 리시버의 클래스명만 등록했으면 클래스 타입 레퍼런스를 이용해(MyReceiver::class.java) 명시적 인텐트로 실행하고, 인텐트 필터를 등록했으면 암시적 인텐트로 실행해야 합니다.

그런데 만약 리시버를 매니페스트 파일에 등록하고 <intent-filter> 태그를 선언했다면 암시적 인텐트로는 실행할 수 없습니다. 물론 코드에서 registerReceiver() 함수로 등록한 리시버는 암시적 인텐트로도 잘 실행됩니다. 이는 백그라운드 제약과 관련된 내용으로, 이후 자세히 살펴보겠습니다.

 

브로드캐스트 리시버를 실행하는 인텐트는 sendBroadcast() 함수로 시스템에 전달 합니다. 그러면 시스템은 브로드캐스트 리시버 객체를 생성하여 실행해 줍니다.

val intent = Intent(this, MyReceiver::class.java)
sendBroadcast(intent)