본문 바로가기
Android/Android 기초

[Android] 안드로이드 4대 컴포넌트(3) - 브로드캐스트(BroadCast)

by 태크민 2023. 9. 3.

브로드캐스트 리시버(Broadcast Receiver)

브로드캐스트 리시버는 다양한 이벤트와 정보를 받아 반응하는 컴포넌트로, 브로드 캐스트 알림에 응답하는 구성요소이다.

안드로이드는 여러 응용프로그램이나 장치에 메시지를 전달하기 위해 방송(Broadcasting) 메시지를 사용한다.

문자메시지 도착, 배터리 방전, SD카드 탈 부착 등 이벤트가 발생하면 시스템은 이 브로드캐스트르를 수신하도록 신청한 모든 앱에게 전송한다.

그리고 브로드캐스트 리시버는 이러한 방송메시지가 발생하면 반응을 한다.

ex) 시스템 부팅완료, 배터리 부족, 문자메시지 수신 등

 


 

브로드 캐스트 리시버 등록 방법

  • 정적으로 등록하는 방법
  • 동적으로 등록하는 방법

1. 정적으로 등록하는 방법

정적 Receiver는 Receiver를 고정해서 등록해놓고 원하는 방송만 수신하는 Receiver이다.

즉, 사용자가 직접 AndroidManifest.xml 파일에 receiver를 등록하는 방식

이 방식은 액티비티의 생명주기에 영향을 미치지 않으며 앱이 실행중이지 않을 때도 메시지를 받을 수 있다.

앱이 현재 실행되고 있지 않으면 시스템이 앱을 시작하고 브로드캐스트를 전달할 수 있다.

기본적으로 앱이 설치될 때 시스템 패키지 관리자가 receiver를 등록한다.

단, Android Oreo(API Level 26) 이상은 몇몇 브로드 캐스트를 제외하고 정적 리시버를 사용할 수 없다. (동적 리시버만 사용 가능)

ex) action android:name="android.intent.action.BOOT_COMPLETED"등 같은 브로드 캐스트는 예외적으로 허용

 

정적 브로드캐스트 리시버 등록 (Manifest)

<activity android:name=".MainActivity">
..
<receiver android:name=".receiver.MyBroadCastReceiver">
    <intent-filter>
	<action android:name="android.intent.action.BOOT_COMPLETED"/>

	//이것은 오레오 이상부터 불가(동적으로 등록해야함)
        <action android:name="com.example.limky.broadcastreceiver.gogo"></action>
    </intent-filter>
</receiver>

 

브로드캐스트 리시버 클래스 구현

public class MyBroadCastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        String actionName = intent.getAction();
        Toast.makeText(context, "받은 액션 : "+actionName , Toast.LENGTH_SHORT).show();
	}
}

 

2. 동적으로 등록하는 방법

액티비티 Context의 registerReceiver() 메소드를 통해 등록할 수 있다.

정적 리시버와 달리 앱이 동작 중인 상태에서만 사용가능 하기 때문에 무의미한 CPU와 배터리 사용을 방지할 수 있다.

하지만 onDestroy(), onPause() 등 생명주기에서 리시버를 해제시켜주지 않으면 메모리 누수로 이어진다.

 

브로드 캐스트 송신

sendBroadcast(new Intent("com.example.limky.broadcastreceiver.gogo"));

 

동적 브로드 캐스트 리시버 등록

public class MainActvity extends AppCompatActivity{
string BROADCAST_MESSAGE="com.example.limky.broadcastreceiver.gogo";
..
..
BroadcastReceiver br=new MyBroadcastReceiver();
    /** 동적으로(코드상으로) 브로드 캐스트를 등록한다. **/
    private void registerReceiver(){
        if(br != null) return;

        final IntentFilter theFilter = new IntentFilter();
        theFilter.addAction(BROADCAST_MESSAGE);
	therFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);

        this.registerReceiver(this.mReceiver, theFilter);

    }
}

 

브로드 캐스트 리시버 클래스 구현

public class MyBroadCastReceiver extends BroadcastReceiver{
	string BROADCAST_MESSAGE="com.example.limky.broadcastreceiver.gogo";
         @Override
         public void onReceive(Context context, Intent intent) {
         	int receviedData = intent.getIntExtra("value",0);
                if(intent.getAction().equals(BROADCAST_MESSAGE)){
                    Toast.makeText(context, "recevied Data : "+receviedData, Toast.LENGTH_SHORT).show();
         	}	
	 }
 }

 

동적 브로드 캐스트 리시버 해제

private void unregisterReceiver() {
          if(mReceiver != null){
              this.unregisterReceiver(mReceiver);
              mReceiver = null;
       	  }
}

 


 

브로드 캐스트 리시버의 상태가 앱에 미치는 영향

브로드 캐스트 리시버의 상태(실행 중인지 아닌지)는 앱의 상태에 영향을 주며, 결과적으로 시스템에 의해 종료될 가능성이 있다.

예를 들어, 프로세스가 브로드 캐스트 리시버를 실행할 때(onReceive 메소드 코드를 실행 중 일 때) 이는 포그라운드 프로세스로 간주된다. 따라서 메모리 부족이 심한 상황을 제외하고 시스템은 프로세스를 계속 실행한다.

하지만 코드가 onReceive()에서 반환되면 브로드캐스트 리시버는 더 이상 활성 상태가 아니다.

onReceive()에서 반환 시 시스템은 이 프로세스를 우선 순위가 낮은 프로세스로 간주하여 더 중요한 다른 프로세스에서 리소스를 사용할 수 있도록 이 프로세스를 종료할 수 있다.

이러한 이유로 브로드 캐스트 리시버에서 장기적으로 백그라운드 스레드를 실행시켜서는 안된다. onReceive() 이후 시스템은 언제든지 프로세스를 종료하여 메모리를 회수할 수 있으며 이 과정에서 프로세스에서 생성되어 실행중인 스레드를 종료할 수 있다.