오늘은 안드로이드 브로드캐스트(Broadcast)에 대해서 알아보자.
회사에서 Bluetooth 통신 관련 코드를 봐야할 일이 생겼는데 브로드캐스트를 남발했더라.
그래서 이참에 대충 알고있던 브로드캐스트에 대해 깔끔하게 정리해보려고 한다.
브로드캐스트(Broadcast)가 무엇일까?
https://developer.android.com/guide/components/broadcasts
안드로이드 공식 홈페이지에 가보면 정의가 자세하게 나와있다.
발행-구독 디자인 패턴과 유사한 안드로이드의 메시지 전달 방식이란다.
하지만, 나같은 초보자들은 크게 와닿지않는다.
간단하게 설명하면 Broadcast란 말처럼 어디선가 방송이 나오고 그 방송을 수신하는 메시지 전달 방식을 말한다.
그럼, 브로드캐스트를 등록하는 방법부터 알아보자.
브로드캐스트를 등록하는 방법에는 2가지가 있다.
1. 정적 Broadcast 등록
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.boo.sample.samplebroadcastreceiver">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SampleBroadcastReceiver">
<receiver android:name=".BroadCastReceiverUsingManifest" android:exported="true">
<intent-filter>
<action android:name="example.test.broadcast"/>
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
위의 코드처럼 manifest 파일에 브로드캐스트 리시버를 등록하는 것을 정적 Broadcast 등록이라한다.
그리고 BroadCastReceiverUsingManifes 클래스를 만들어서 BroadcastReceiver를 구현해주면 된다.
class BroadCastReceiverUsingManifest : BroadcastReceiver() {
val TAG = this::class.java.simpleName
override fun onReceive(context: Context?, intent: Intent?) {
if(intent?.action.equals("example.test.broadcast")){
Toast.makeText(context, "Customize broadcast!", Toast.LENGTH_LONG).show()
Log.d(TAG, "onReceive: BATTERY CHANGED")
}
}
}
이렇게되면 manifest 파일에 intent-filter에 등록한 action이 발생하면 BroadCastReceiverUsingManifest 클래스에 있는 onReceiver가 반응하게된다.
2. 동적 Broadcast 등록
동적인 Broadcast등록은 말그대로 런타임시에 Broadcast를 등록해주는 것을 말한다.
매니페스트 파일에 등록해줄 필요가 없다.
class MainActivity : AppCompatActivity() {
val TAG = this::class.java.simpleName
val br = object: BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
if(intent?.action.equals(Intent.ACTION_BATTERY_CHANGED)){
Log.d(TAG, "onReceive: Battery status is changed")
}else if(intent?.action.equals(Intent.ACTION_SCREEN_ON)){
Log.d(TAG, "onReceive: Screen On")
}else if(intent?.action.equals("example.test.broadcast")){
Toast.makeText(context, "Customize broadcast!", Toast.LENGTH_LONG).show()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendButton = findViewById<Button>(R.id.send_broadcast)
sendButton.setOnClickListener {
val intent = Intent()
intent.action = "example.test.broadcast"
sendBroadcast(intent)
}
}
override fun onResume() {
super.onResume()
val filter = IntentFilter()
filter.addAction(Intent.ACTION_BATTERY_CHANGED)
filter.addAction(Intent.ACTION_SCREEN_ON)
registerReceiver(br, filter)
}
override fun onPause() {
super.onPause()
unregisterReceiver(br)
}
}
BroadcastReceiver를 구현해서 onReceiver를 override해준다.
해당하는 Intent.action에 따라 내가 원하는 코드를 적어주면 된다.
그리고 onResume()에서 브로드캐스트리시버가 받을 액션을 IntentFilter에 적어주고 등록한다.
onPause()에는 unregisterReceiver 함수를 등록해준다.
👉여기서 주의할 점이 onResume()에 등록했으면 onPause()에서 해제해주어야하고 onCreate()에서 등록했으면 onDestroy()에서 해제해주어한다.
이제 R.id.send_broadcast 버튼을 누르면 onReceiver에서 메시지를 받게된다.
✋잠깐!
브로드캐스트와 관련해서 중요한 내용이 있는데 꼭 알고가자!
공식 홈페이지( https://developer.android.com/about/versions/oreo/background#broadcasts )에도 나온 내용이다.
브로드캐스트가 너무 남발하면서 핸드폰 리소스가 너무 낭비되는 현상때문에 브로드캐스트에 제한이 걸렸다.
중요한 것만 요약하자면 Android 8.0이상부터 암시적 브로드캐스트(implicit broadcast)는 더이상 정적인 등록을 할 수가 없게 됐다.
무슨 말일까? ㅋㅋ
나도 처음에 암시적 브로드캐스트가 무슨말인지 몰라서 헤맸다.
일단 암시적과 명시적 인텐트에 대해서 알아야하는데....
암시적 브로드캐스트란?
특정 앱, 클래스, 패키지를 나타내지 않는 브로드캐스트를 말합니다.
위 공식 홈페이지에 나온 예를 들면, ACTION_PACKAGE_REPLACED는 암시적 브로드캐스트입니다.
앱이 재설치되어서 패키지 이름이 바뀔 때 호출되는 브로드캐스트인데 어떤 특정 앱만이 패키지가 바뀐다고 생각할 수 없으니까요.
반면에, ACTION_MY_PACKAGE_REPLACED는 명시적 브로드캐스트입니다.
왜냐하면, 지금 현재 앱이 재설치가되어 패키지명이 바뀌었을 때 브로드캐스트를 보내기때문입니다.
따라서 브로드캐스트를 manifest에 등록할 때는 ACTION_MY_PACKAGE_REPLACED만 등록할 수 있습니다.
➕ 런타임에 등록하는 동적 브로드캐스트 등록은 명시적, 암시적 따질 것 없이 다 가능합니다.
➕ signature permission이 필요한 브로드캐스트도 권한이 허락한 앱만 브로드캐스트를 수신할 수 있기 대문에 동적, 정적 등록 상관없이 사용 가능합니다.
댓글 없음:
댓글 쓰기