ANR은 "Application Not Responding"의 약자로 번역하자면 "애플리케이션 응답하지 않음" 이란 뜻입니다. 간혹 상용 앱을 사용하거나 기능 구현 후 테스트 하는 도중 마주치게 되는 문구인데, Android Developers에서 말하는 ANR은 다음과 같습니다.
Android 앱의 UI 쓰레드가 너무 오랫동안차단되면 ANR 오류가 발생한다. 앱이 포그라운드에 있으면 아래 그림과 같이 사용자에게 대화상자를 표시합니다.
메인 쓰레드를 어디선가 점유하고 있다면 사용자의 키 입력 이벤트(메뉴키, 뒤로가기 키, 볼륨키 등)를 전달하지 못한다. 만약 일정 시간 이상 이벤트를 전달 못한 경우, ANR이 발생한다. 위에 정의되어 있는 상수들 중 아래에 해당한다. 5초 이상 키 이벤트가 지연될 경우 ANR을 발생하도록 한다.
static final int KEY_DISPATCHING_TIMEOUT = 5 * 1000
홈키와 전원 키는 워낙 중요한 키 이므로 앱과 별개로 동작합니다. 즉 ANR과는 무관합니다.
Foreground Broadcast, Background Broadcast에 대한 ANR 타임아웃을 정의해놓은 것입니다.
static final int BRAODCAST_FG_TIMEOUT = 10 1000;
static final int BROADCAST_BG_TIMEOUT = 60 1000;
위에서 말하는 타임아웃은 즉 브로드캐스트의 리시버의 onReceive()가 얼마나 작업을 수행하고 있냐에 대한 타임아웃입니다.
Foreground Broadcast의 경우에는 메세지 처리 우선순위가 더 높지만 ANR이 발생하는 타임아웃 제한은 더 짧습니다. 왜냐하면 포그랑ㄴ드에서 동작하는 만큼 사용자에게 영향을 끼칠 가능성이 더 높기 때문에 우선순위를 높게 책정한 이유 역시 ANR 타임아웃이 작기 때문에 빨리 처리해야합니다.
요약하자면 다음과 같습니다.
- 액티비티가 포그라운드에 있는 동안 앱이 입력 이벤트 또는 브로드 캐스트 리시버(키 누름 또는 화면 터치 이벤트)에 5초 이내에 응답하지 못함
- 포그라운드에 액티비티가 없을 때 브로드캐스트 리시버가 상당한 시간 내에 실행을 완료하지 못함
결론은 메인 쓰레드가 일정 시간 동안 작업을 처리하지 못하면 발생하는 에러라는 뜻이다.
UI Thread 최적화
: UI Thread에서 실행되는 메서드는 가능한 한 작업을 적게 실행해야 합니다.
장기 작업은 Coroutine을 활용합니다.
: API 30에서 AsyncTask가 Deprecated되었습니다. 따라서 Coroutine을 활용하여 장기 작업을 처리합니다.
BroadcastReceiver 활용 시 효율적으로 사용