안드로이드/Deep in the AOS

BroadcastReceiver :: 앱 구성 요소 4대 컴포넌트 [ Deep in the AOS ]

Android Developer에선 Broadcast를 다음과 같이 설명합니다.

Android 앱은 Android 시스템 및 기타 Android 앱에서 게시 - 구독 디자인 패턴과 유사한 Broadcast Message를 받거나 보낼 수 있습니다.
관심 있는 이벤트가 발생할 때 Broadcast가 전송됩니다.
예를 들어, 시스템 부팅 또는 기기 충전 시작과 같은 다양한 시스템 이벤트가 발생할 때 Broadcast를 전송합니다.
앱은 특정 Broadcast를 수신하도록 등록할 수 있습니다.
Broadcast가 전송되면 시스템은 특정 유형의 Broadcast를 수신하도록 신청한 앱에 Broadcast를 자동으로 라우팅합니다.
이런 Broadcast는 앱 전체, 일반 사용자 플로우 외부에서 메시징 시스템으로 사용될 수 있습니다.

Broadcast를 받기 위해서는 Broadcast Receiver가 필요합니다.

Broadcast Receiver를 "이벤트 모델로 수행되는 컴포넌트" 라고 부릅니다.

🧐 왜 이벤트 모델로 수행되는 컴포넌트로 부를까요?

Broadcast Receiver는 Intent를 통해 실행이 되는데, 지난 번 Activity에서 사용한 Intent와 비교해보겠습니다.

Activity에서 인텐트 동작

1. Activity에서 다른 Activity로 실행할 때 Intent의 정보, 타입이 일치하다면 성공적으로 다른 Activity로 실행이 됩니다.

2. Intent를 통해 다른 Activity를 실행하려고 하는데 액티비티가 N개면 선택을 해서 하나만 실행이 됩니다.

3. Intent의 정보가 일치하지 않을 때는 실행이 되지 않고 Error가 발생합니다. ( ex: Action을 View로 했는데 Action이 Send인 형식을 불러올 때 )

 

Broadcast Receiver에서 인텐트 동작

타입이 맞지 않거나 존재하지 않을 때 ex) Broadcast 중 배터리가 낮을 때 action이 존재하지 않을 때

1. (타입이 맞지 않는 경우) Intent가 발생 ( Action이 맞지 않는 경우에도 실행되지 않고 에러가 발생하지 않음 )

 

타입이 맞고 존재할 때 ex) 배터리가 낮을 때 Broadcast 중 배터리가 낮을 때 action이 존재할 때

2. (타입이 맞는 경우)Intent가 발생 ( 실행 Broadcast가 N개라면 N개 모두 실행 )

 

Broadcast Receiver는 왜 사용할까요?

Android의 Component인 Activity는 화면 표현이 목적입니다.

Service는 백그라운드에서의 로직 구현이 목적입니다.

Content Provider는 앱 간 데이터 공유가 목적입니다.

Broadcast Receiver는 특정한 목적이 존재하지 않습니다.

왜일까요? 🧐

Broadcast Receiver가 세상에 나타난 이유는 (없으면 그만 있으면 전부 해줘) 작업이 가능한 Component가 필요해서 입니다.

만약, 배터리가 적을 때 이벤트를 발생시키고 싶다면 백그라운드에서 지속적인 서비스를 진행해야겠지요

이 백그라운드 서비스가 지속적으로 동작한다면 배터리 소모도 문제지만 갑자기 죽어버리는 경우가 있을 수 있습니다.

그러면 우리는 배터리가 적을 때 이벤트를 발생시킬 수 없는 상황이 나타날 수 있습니다.

이런 Broadcast Receiver의 좋은 점은 평상 시 아무 행동도 하지 않고 대기하고 있다가 OS에서 특정 Broadcast를 수신했을 때 원하는 Intent(Action)이 존재하면 행동하고 없다면 다시 대기하기 때문에 효율적이라고 할 수 있습니다.

그래서 특정 상황에서 필요한 기능을 백그라운드 실행하기 위해 Broadcast를 전송해주기로 했습니다.

종류가 굉장히 많습니다. 배터리가 적을 때, 부팅했을 때, 전화할 때 등...

 

📨 Broadcast 전송 방법

1. sendBroadcast(Intent)

정의되지 않은 순서로 모든 수신자에 브로드캐스트를 전송합니다.

일반적으로 사용하는 Broadcast 전송 방식입니다.

Android Developer에선 sendBroadcast가 상당히 효율적이지만 수신자가 다른 수신자의 결과를 읽거나 브로드캐스트로부터 수신한 데이터를 전파하거나 브로드캐스트를 중단할 수 없음을 의미한다고 합니다.

 

2. sendOrderedBroadcast(Intent, String)

한 번에 하나의 Broadcast Receiver에 Broadcast를 전송합니다.

각 Broadcast Receiver는 차례로 실행되기 때문에 결과를 다음 수신자로 전파하거나 Broadcast를 완전히 중단해 Broadcast가 다른 수신자로 전달되지 않도록 할 수 있습니다.

실행되는 순서는 일치하는 Intent-filter의 android:priority 속성으로 제어할 수 있습니다.

만약 동일한 priority를 지닐 때는 임의의 순서로 실행됩니다.

 

3. LocalBroadcastManager.sendBroadcast

발신자와 동일한 앱에 있는 Broadcast Receiver에게 Broadcast를 전송합니다.

다른 앱으로 Broadcast를 전송할 필요가 없다면 LocalBroadcastManager.sendBroadcast를 사용합니다.

구현이 효율적(프로세스 간 통신 필요 없음)이고 Broadcast를 수신하거나 전송할 수 있는 다른 앱과 관련된 보안 문제를 걱정하지 않아도 됩니다.

 

Broadcast Message는 Intent 객체에서 래핑되기 때문에 Intent의 작업 문자열은 앱의 자바 패키지 이름 구문을 제공하고 Broadcast Event를 고유하게 식별해야 합니다.

putExtra(String, Bundle)을 통해 Intent에 추가 정보를 넣을 수 있으며 setPackage(String)을 호출해 동일한 조직의 앱 세트로 Broadcast를 제한할 수 있습니다.

 

※ startActivity(Intent) 같이 Activity를 실행하거나 Broadcast를 전송하는 데 모두 Intent를 사용하지만, 서로 전혀 관련이 없다는 것을 참고하면 좋습니다.