브로드캐스트 리시버

1 minute read

브로드캐스트 리시버는 안드로이드 4대 구성 요소 중 하나다. 브로드캐스트 리시버에 대해 이해한 것을 정리해보려 한다.

브로드캐스트란?

브로드캐스트는 방송이라는 뜻으로, 안드로이드에서는 publish-subscribe 패턴과 비슷한 느낌으로 브로드캐스트를 전송하고 수신할 수 있다. 브로드캐스트는 시스템 또는 사용자(개발자)가 전송할 수 있다. 시스템의 경우 시스템 부팅 또는 기기 충전 시작할 때 등 다양한 시스템 이벤트 시 브로드캐스트를 전송한다. 또 사용자(개발자)는 앱 내에서 브로드캐스트를 전송해 동일 앱 내 다른 구성 요소 또는 다른 앱이 수신할 수 있도록 할 수 있다.

브로드캐스트 리시버란?

브로드캐스트 리시버는 브로드캐스트를 수신할 수 있는 객체다. onReceive() 메서드를 오버라이딩하여 수신 시 동작을 지정할 수 있다.
브로드캐스트 리시버를 등록하는 법은 두가지가 있다.

manifest에 등록

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
    </intent-filter>
</receiver>

AndroidManifest.xml에 <reciever>를 등록할 수 있다. 이런 식으로 하면 앱이 설치될 때 시스템 패키지 관리자가 리시버를 등록한다. 앱이 실행되고 있지 않을 때 브로드캐스트를 수신하면 리시버를 진입점으로 앱이 실행된다.
단, API 레벨 26 이상부터는 대다수의 암시적 브로드캐스트를 manifest에 등록할 수 없다.

참고: 암시적 브로드캐스트 예외

동적으로 등록

class AnotherActivity : AppCompatActivity() {

    private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Toast.makeText(applicationContext, "Received", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_another)
        val filter = IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)
        registerReceiver(broadcastReceiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(broadcastReceiver)
    }
}

broadcastReceiver를 익명 클래스로 정의하고, onCreate()에서 등록, onDestroy()에서 해제하는 과정이다. 만약 onResume()에서 등록했으면 onPause()에서 해제해야 한다. 이렇게 해야 불필요한 브로드캐스트 수신을 방지할 수 있다.
IntentFilterIntent.ACTION_AIRPLANE_MODE_CHANGED로 해 비행기 모드 전환 시 시스템 브로드캐스틀 수신해 토스트 메시지로 출력한다.

브로드캐스트 전송

브로드캐스트 전송 방법은 세가지가 있다.

sendOrderedBroadcast

모든 수신자에게 브로드캐스트를 전송하는 방식이다.

LocalBroadcastManager.sendBroadcast

동일한 앱 내의 수신자에게 전송하는 방식이다. IPC가 필요 없어 구현이 효율적이고 다른 앱에서 수신할 수 없기 때문에 보안성이 더 좋다. Register와 unregister를 LocalBroadcastManager로 해야 한다.

예제

한 액티비티에서 로컬 브로드캐스트 전송과 수신을 하여 토스트 메시지 출력을 하는 코드다.

class AnotherActivity : AppCompatActivity() {

    private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent?.let {
                Toast.makeText(
                    applicationContext,
                    it.getStringExtra("SOME_STRING"),
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_another)

        val button = findViewById<Button>(R.id.btn_broadcast)
        button.setOnClickListener {
            val intent = Intent("com.example.exampleapplication.ACTION_BROADCAST").apply {
                putExtra("SOME_STRING", "Broadcasting...")
            }
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
        }

        val filter = IntentFilter("com.example.exampleapplication.ACTION_BROADCAST")
        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver)
    }
}

Comments