Android

[Android] 백그라운드 제약(Background Execution Limit), 발생 오류

haehyun 2022. 1. 23. 20:55
728x90

백그라운드 제약(Background Execution Limit)

  • 앱이 백그라운드 상황일 때 작업 처리에 받는 제약들.
  • 브로드캐스트 제약 : 브로드캐스트 리시버(Broadcast Receiver) 컴포넌트 실행에 대한 제약
  • 백그라운드 서비스 제약 : 서비스(Service) 컴포넌트 실행에 대한 제약
  • 액티비티와 달리 화면이 없는 상태에서 실행되며, 백그라운드에서 실행될 때마다 앱이 기기의 제한된 리소스(ex: RAM)을 사용해 사용자 환경이 손상될 수 있기 때문에 Android 8.0(API Level 26) 부터 백그라운드 작업에 대해 여러 제약이 생겼다.
  • ex) 사용자가 현재 창에서 게임을 하면서 다른 창으로 웹을 탐색하고, 타사 앱을 사용해 백그라운드로 음악을 재생하는 경우 동시에 실행되는 앱들로 인해 시스템 부하가 걸리는데, 이 때 추가 앱이나 서비스가 백그라운드에서 실행중이면 시스템 부하가 더욱 가중된다. 이러한 부하 때문에 앱이 강제로 종료될 수 있다.
  • 이러한 문제를 줄이기 위해 사용자가 앱과 직접 상호작용하지 않을 때 이 앱이 수행할 수 있는 작업을 제한한다.

요약 : 어쨌거나 모든 프로그램에서 최대한 막아야 하는 건 앱이 강제 종료되는 상황....😥 강종을 일으키는 원인 중 하나인 시스템 과부화를 방지하기 위해 문제를 일으킬만한 행동들을 못 하도록 안드로이드 측에서 미리 제한해두는 것.

 

브로드캐스트 제약

Background execution not allowed: receiving Intent { act=ACT_RECEIVER flg=0x10 } to com.example.test/.MyReceiver
  • 매니페스트 파일에 등록한 리시버는 암시적 인텐트로 실행할 수 없다.
  • 내부 앱이든 외부 앱이든 registerReceiver()로 동적 생성한 리시버만 암시적 인텐트로 실행할 수 있다.
    • 매니페스트 파일에 등록한 리시버명시적 인텐트O, 암시적 인텐트X
    • 매니페스트 파일에 등록하지 않은 리시버, 동적 생성 → 명시적 인텐트X, 암시적 인텐트O

 

*리시버 생성 및 실행 방법

  • 정적 생성 (미리 만들어두고 사용하는 방법)
    1. Receiver 파일을 생성, BoradcastReceiver를 상속받는 클래스 선언
    2. onReceive() 함수 오버라이딩
    3. 매니페스트 파일에 등록
      (클래스명을 나타내는 name속성 필수, 암시적 인텐트 할거면 <intent-filter> 추가)
    4. 명시적 인텐트 or 암시적 인텐트로 서비스를 실행하는 인텐트 생성
    5. sendBroadcast() 함수로 인텐트 전달
  • 동적 생성 (바로 만들어서 사용하는 방법)
    1. BroadcastReceiver를 상속받는 익명 클래스(객체) 선언
    2. onReceive() 함수 오버라이딩
    3. registerReceiver() 함수에 리시버 객체, 인텐트 필터를 전달해 리시버 등록
    4. 암시적 인텐트로 서비스를 실행하는 인텐트 생성
    5. sendBroadcast() 함수로 인텐트 전달

 

*인텐트 생성 방법

  • 암시적 인텐트 : 인텐트 필터로 인텐트를 생성하는 방법.
  • 명시적 인텐트 : 클래스 레퍼런스 타입으로 인텐트를 생성하는 방법.

 

백그라운드 서비스 제약

Not allowed to start service Intent { act=ACTION_OUTER_SERVICE pkg=com.example.test }: app is in background uid null
  • 앱이 백그라운드 상태일 때 인텐트를 전달하면 오류가 발생해 서비스가 실행할 수 없다.

 

Context.startForegroundService() did not then call Service.startForeground()
  • 일반적인 startService() 함수가 아니라 startForegroundService() 함수로 인텐트를 전달하면 백그라운드 상태에서도 앱이 실행되기는 하나, 잠시 후 다른 오류가 발생한다.
  • 인텐트를 startForegroundService()로 실행한 뒤, 빠른 시간안에 startForeground() 함수를 호출해 포그라운드 상황으로 만들면 서비스를 정상 실행할 수 있다.
    ex) 액티비티 코드에서 startForegroundService()로 서비스 실행 → 서비스 코드에서 startForeground() 호출
  • 이 때 startForeground() 함수 매개변수로 Notification객체가 전달되는데, 이건 즉 사용자에게 푸시 알림을 띄우는 행동. 즉, 백그라운드 상황에서 프로그램을 실행하고 싶다면 이 앱이 실행되고 있다는 것을 사용자에게 알려야 한다는 의미이다.
  • 참고로 startForground() 함수를 사용하려면 퍼미션을 등록해야 한다.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

 


참고자료

728x90