암시적 선언(정적 선언)된 BroadCastReceiver는 앱을 실행시킬 수 있다.

지프치프·2023년 5월 12일
0

Android

목록 보기
64/89
post-thumbnail

“Android 로봇은 Google에서 제작하여 공유한 저작물을 복제하거나 수정한 것으로 Creative Commons 3.0 저작자 표시 라이선스의 약관에 따라 사용되었습니다.”


BroadcastReceiver

BroadcastReceiver란 시스템에서 발생하는 특정 이벤트들을 수신받을 수 있는 Receiver이다. 자세한 설명은 필자가 이전에 작성한 포스팅을 참고하면 도움이 될 것이다.

암시적 선언(정적 선언)?

AndroidManifest.xml에서 선언하는 것을 암시적 선언(정적 선언)이라고 한다.
Android Developer의 따르면..

If you declare a broadcast receiver in your manifest, the system launches your app (if the app is not already running) when the broadcast is sent.

AndroidManifest를 통해 정적으로 선언을 하면 앱이 실행 중이 아니더라도 등록한 이벤트가 발생하면 시스템에서 앱을 실행시킬 수 있다고 한다.

어떻게 가능한걸까 ..?
이 또한 아래와 같이 안내하고 있었다.

The system package manager registers the receiver when the app is installed. The receiver then becomes a separate entry point into your app which means that the system can start the app and deliver the broadcast if the app is not currently running.

앱이 설치될 때 패키지 매니저가 해당 앱을 리시버에 등록해주면 시스템에서 접근 가능한 진입점이 생기기 때문에 앱을 실행시킬 수 있다고 한다.

굉장히 쓰임새가 많아 보이지만 안타깝게도 지난 포스팅에서도 작성했듯이
API level 26부터 제한되어 targetSDK가 26 이상이라면 작동하지 않는다.

다만 예외로 사용 가능한 시스템 이벤트들이 있다.
전화 발신/수신, 부팅 완료 등
일반적인 상황에서 쓰는건 없어보인다.
에외로 사용 가능한 이벤트 목록은 가이드 문서를 통해 확인할 수 있다.

배터리 이슈

StackOverflow를 살펴보던 중 눈에 띄는 한 문구를 발견했다.

You should be careful while adding broadcast receiver because unnecessary broadcast receivers drain battery power.

불필요한 BroadcastReceiver들은 배터리를 소모할 수도 있다고 한다.
그렇다면 사용되지 않는 경우가 있다면 BroadcastReceiver를 시스템에서 해지해야한다.

에를 들면 앱 기능 상 필요하기 때문에 암시적 선언으로 구현했지만
해당 기능이 필요하지 않아 사용하지 않는 사용자가 있다면?

배터리 소모를 줄이기 위해 비활성화 할 수 있는 옵션을 제공해야 할 것이다.
AndoridManifest에 등록했기 때문에 해지할 방법은 없을 줄 알았지만
역시나 해지할 방법은 있었다.

앱이 설치될 때 패키지 매니저가 Receiver를 시스템에 등록한다고 위에서 설명했었다. 반대로 말하자면 패키지 매니저를 사용하여 해지도 할 수 있었다.

Code

// 시스템에 등록한 Recevier의 ComponentName을 가져온다.
ComponentName component = new ComponentName(context, MyReceiver.class);

// PackageManager를 통해 Receiver의 현재 상태 확인
int status = context.getPackageManager().getComponentEnabledSetting(component);
if(status == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
    Log.d("receiver is enabled");
} else if(status == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
    Log.d("receiver is disabled");
}

/**
 * 각 상태에 따라 아래의 메소드를 취사선택하여 활성화 상태를 설정 가능
 */
//Disable
context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED , PackageManager.DONT_KILL_APP);
//Enable
context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED , PackageManager.DONT_KILL_APP);

개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.

profile
지프처럼 거침없는 개발을 하고싶은 개발자

0개의 댓글