관리 메뉴

나만을 위한 블로그

[Android] ANR이란? 본문

Android

[Android] ANR이란?

참깨빵위에참깨빵 2021. 10. 14. 00:57
728x90
반응형

ANR은 "Application Not Responding"의 약자로 번역하면 "애플리케이션이 응답하지 않음"이란 뜻이다.

간혹 상용 앱을 사용하거나 기능 구현 후 테스트하는 도중 마주치게 되는 문구인데, 안드로이드 디벨로퍼에서 말하는 ANR은 아래와 같다.

 

https://developer.android.com/topic/performance/vitals/anr?hl=ko 

 

ANR  |  Android 개발자  |  Android Developers

ANR Android 앱의 UI 스레드가 너무 오랫동안 차단되면 'ANR(애플리케이션 응답 없음)' 오류가 트리거됩니다. 앱이 포그라운드에 있으면 그림 1에서와 같이 시스템에서 사용자에게 대화상자를 표시합

developer.android.com

Android 앱의 UI 쓰레드가 너무 오랫동안 차단되면 ANR 오류가 발생한다. 앱이 포그라운드에 있으면 아래 그림과 같이 사용자에게 대화상자를 표시한다. 사용자가 ANR 대화상자에서 앱을 강제종료할 수 있다.
ANR은 UI 업데이트를 담당하는 앱의 기본 쓰레드가 사용자 입력 이벤트 또는 그림을 처리하지 못해 사용자 불만을 초래하므로 문제가 된다. 다음 조건 중 하나가 발생하면 앱 관련 ANR이 발생한다.

- 액티비티가 포그라운드에 있는 동안 앱이 입력 이벤트 또는 브로드캐스트 리시버(키 누름 또는 화면 터치 이벤트)에 5초 이내에 응답하지 못함
- 포그라운드에 액티비티가 없을 때 브로드캐스트 리시버가 상당한 시간 내에 실행을 완료하지 못함

 

위 글에서 말하는 그림이란 아래 이미지다.

 

결론은 메인 쓰레드가 일정 시간 동안 작업을 처리하지 못하면 발생하는 에러라는 뜻이다.

ANR의 발동 조건도 쓰여져 있지만 좀 더 정확한 발동 조건을 설명하는 곳은 없는지 찾아봤다.

 

https://itmining.tistory.com/3

 

[안드로이드] ANR의 의미와 예방

이 글은 PC 버전 TISTORY에 최적화 되어있습니다. 서론 안드로이드 앱을 구현하여 돌리다보면, 또는 플레이스토어에 올라온 앱임에도 불구하고, 앱의 중지를 알리는 메시지를 심심치 않게 봤을 것

itmining.tistory.com

1. Input 이벤트(키를 누르거나 화면 터치 등)에 5초 안에 반응하지 않을 때
2. 브로드캐스트 리시버가 10초 내로 실행을 끝내지 않을 때(UI가 없는 브로드캐스트 리시버, 서비스도 실행 주체는 메인 쓰레드이므로 긴 시간을 소모하는 작업일 경우 ANR을 발생시킴)

 

보면 ANR이 발동하는 경우는 메인 쓰레드에서 많은 작업을 할 때다. UI를 수정할 수 있는 건 메인 쓰레드 뿐이라 여기에 너무 많은 작업을 요청하면 그걸 버티지 못하고 ANR 에러를 내면서 앱이 다운되버린다.

디벨로퍼에선 ANR 발생 시 진단하는 방법도 서술하고 있다.

 

ANR을 진단할 때 다음과 같은 일반 패턴을 찾아야 한다.

1. 앱이 기본 쓰레드에서 I/O와 관련된 느린 작업을 실행 중이다
2. 앱이 기본 쓰레드에서 긴 계산을 실행 중이다
3. 기본 쓰레드에서 다른 프로세스에 관한 동기 바인더 호출을 실행 중이고 다른 프로세스가 반환하는 데 오랜 시간이 걸린다
4. 다른 쓰레드에서 발생하는 긴 작업을 위해 동기화된 블록을 대기하는 동안 기본 쓰레드가 차단됐다
5. 기본 쓰레드가 프로세스에서 또는 바인더 호출을 통해 다른 쓰레드와 교착 상태에 있다. 기본 쓰레드가 긴 작업이 완료될 때까지 대기하는 것만이 아니라 교착 상태에 있다

 

해결하는 방법은 안드로이드 디벨로퍼에선 기본 쓰레드에서 실행되는 작업을 워커(작업자) 쓰레드로 이동시키라고 한다.

그 외에 다른 방법은 없는지 찾아봤다.

 

https://www.charlezz.com/?p=850 

 

ANR이란? (Android Not Responding) | 찰스의 안드로이드

ANR? 애플리케이션을 개발 하다보면 위 이미지와 같은 ANR 다이얼로그를 종종 볼때가 있습니다. 안드로이드 시스템에서는 일정 시간 사용자와 상호작용이 불가능할 때 애플리케이션의 강제종료

www.charlezz.com

시간이 많이 걸리는 작업은 서브 쓰레드에서 동작하게 해서 메인 쓰레드의 부하를 줄이면 된다

- 서브 쓰레드에서 시간이 오래 걸리는 작업을 수행하고 핸들러를 써서 작업 상태 메시지를 메인 쓰레드에 전달한다
- AsyncTask를 써서 핸들러 없이 작업과 작업 내용을 실시간으로 UI에 업데이트한다
- Rxjava의 스케줄러를 이용해 서브 쓰레드에서 작업한다

 

AsyncTask는 현재 deprecated된 상태인데, 비동기 통신으로 UI를 수정해야 한다면 레트로핏과 Volley라는 네트워킹 라이브러리가 있어 이를 사용하면 된다.

안드로이드에서 반응형 프로그래밍 시 사용되는 Rxjava의 스케줄러는 Rxjava 코드가 어떤 쓰레드에서 실행되게 할지 정해주는 역할을 하는데, Rxjava만 쓴다고 비동기 처리가 되는 게 아니라 스케줄러를 통해 쓰레드를 분리해줘야 비동기 처리가 가능해진다. subscribeOn(), observeOn() 연산자를 통해 각각 설정할 수 있다.

 

https://www.geeksforgeeks.org/what-is-anr-and-how-it-can-be-prevented-in-android/

 

What is ANR and How it Can be Prevented in Android? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

...(중략) 충돌은 처리되지 않은 앱 내 예외가 발생한 경우다. 예를 들어 EditText의 텍스트를 설정하려 하지만 EditText가 null이고 예외를 잡기 위한 try-catch 문이 없는 경우, 앱이 충돌하고 강제 종료될 수 있다. 사용자는 충돌의 원인을 볼 수 없으며 앱이 예기치 않게 강제 종료됐고 버그 보고서를 보낼 수 있다는 대화 상자가 표시된다.
메인 쓰레드에서 무거운 작업을 하지 말고 대신 IntentService, AsyncTask, Handler, 다른 쓰레드와 같은 워커 쓰레드를 사용해라. ANR이 발생하는 위치를 감지하는 것은 영구 블록(예 : 일부 잠금을 획득하는 교착 상태)인 경우 간단하지만 일시적인 지연인 경우 더 어렵다. 먼저 취약한 부분과 장기 실행 작업에 대해 코드와 모양을 재평가하라. 예에는 이벤트 쓰레드 안에서 소켓, 잠금, 쓰레드 절전 및 기타 차단 작업 사용이 포함될 수 있다. 이 모든 것이 별도의 쓰레드에서 발생하는지 확인해야 한다

 

결국 메인 쓰레드에서 수행하는 작업들이 너무 많으면 메인 쓰레드가 뻗어버리니까 적당히 쓰레드 만들어서 작업을 나눠 처리하게 하란 뜻이다. try-catch 문을 활용하는 것도 하나의 방법이라 한다.

반응형
Comments