ANR (Application Not Responding)
메인 스레드에서의 작업 대기 시간이 너무 길어졌을 때 타임아웃이 발생한다. ANR이 발생하면 사용자에게 앱을 종료할 것인지 대기할 것인지 묻는 과정을 거친다.
1. ANR 타임아웃
ANR 타임아웃은 시스템이 ANR을 발생시키는 기준이 되는 시간을 의미하며, 젤리빈 이후 브로드캐스트 타임아웃에 변화가 생겼다.
젤리빈 이전
- 브로드캐스트 타임아웃 : 10초
- 서비스 타임아웃 : 20초
- 인풋 디스패칭 타임아웃 : 5초
젤리빈 이후
- 브로드캐스트 타임아웃 (FG) : 10초
- 브로드캐스트 타임아웃 (BG) : 60초
- 서비스 타임아웃 : 20초
- 인풋 디스패칭 타임아웃 : 5초
젤리빈 이후부터는 특별히 명시를 하지 않으면 브로드캐스트 타임아웃이 1분으로 적용된다. 브로드캐스트 리시버를 백그라운드에서 실행하려면 Intent 플래그로 Intent.FLAG_RECEIVER_FOREGROUND를 추가하면된다. ActivityManagerService에는 포그라운드/백그라운드 용도의 BroadcastQueue가 각각 있으며, 큐에 쌓이는 순서과 관계없이 포그라운드 BroadcastQueue가 먼저 처리된다.
2. 안드로이드에서 ANR 판단
ANR이 발생하면 ActivityManagerService에서 appNotResponding() 메서드를 호출하고 이 안에서 다이얼로그를 띄우는 등의 처리를 한다.
Broadcase Receiver와 Service는 Handler를 이용해서 ANR을 판단한다.
Broadcase Receiver와 Service는 시작 전에 Handler의 sendMessageAtTime()을 사용하여 Message를 보내고, 타임아웃이 되면 appNotResponding()을 호출한다. Broadcase Receiver의 onReceive()가 메인 스레드에서 1분 이상 지속되면 Handler에 전달된 Message가 처리된다. 이때 별도의 프로세스(system_server)에서 실행되는 ActivityManagerService에서 처리되기 때문에 앱의 메인 스레드에서의 작업과 관계 없이 제 시간에 처리될 수 있다.
화면 터치와 키 입력 시 ANR
키 입력 이벤트는 커널에서 네이티브(cpp) 단을 거쳐서 앱으로 전달된다. 네이티브 단인 InputDispatcher가 앱에 이벤트를 전달할 때 전달할 Windows를 찾아서 isWindowReadyForMoreInputLocked() 메서드를 통해 기존 이벤트를 처리하느라 대기상태에 있는지 판단해야한다. 대기 상태라면 기존 이벤트가 끝날 때까지 기다리다가 타임아웃이 되면 InputManagerService를 통해 ActivityManagerService의 appNotResponding()을 호출하여 ANR을 발생시킨다.
- 키 이벤트의 ANR
메인 스레드를 어디선가 점유하고 있어서 키 이벤트를 전달하지 못하고 대기 상태에서 타임아웃 시간이 지나면 ANR이 발생한다. 볼륨, 메뉴, 백 키의 경우는 키가 눌린 후 5초 이상 지연 시 바로 ANR이 발생한다. (홈, 전원 키는 앱과 별개로 동작하므로 ANR과 무관)
- 화면 터치 이벤트의 ANR
터치 이벤트의 경우는 메인 스레드가 사용중이라면 대기하는 것은 동일하지만, 타임아웃 시간이 넘어도 바로 ANR이 발생하지 않는다. 그 다음으로 이어서 터치 이벤트가 발생할 때, 두 번째 이벤트의 대기시간이 타임아웃을 넘는다면 ANR이 발생한다. 즉, 두 번째 터치 이벤트가 발생한 후 5초가 지나면 ANR이 발생한다.
서비스나 브로드캐스트 리시버도 메인 스레드를 5초 이상 잡고있다면, 그 사이에 터치 이벤트 발생 시 ANR이 발생할 수 있다. 따라서 오래걸리는 작업은 서비스의 백그라운드 스레드에서 처리해야한다.
'Android > 안드로이드 프로그래밍 Next Step' 카테고리의 다른 글
안드로이드 프로그래밍 Next Step - 3.2 AsyncTask (0) | 2019.03.28 |
---|---|
안드로이드 프로그래밍 Next Step - 3.1 HandlerThread (0) | 2019.03.28 |
안드로이드 프로그래밍 Next Step - 2.1 메인 스레드와 Handler (0) | 2019.03.24 |
안드로이드 프로그래밍 Next Step - 1.3 안드로이드 버전 (0) | 2019.03.23 |
댓글