일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 2022 플러터 설치
- 안드로이드 유닛 테스트
- 큐 자바 코드
- android ar 개발
- Rxjava Observable
- 안드로이드 라이선스
- 멤버변수
- 자바 다형성
- rxjava disposable
- 안드로이드 유닛테스트란
- 안드로이드 os 구조
- 객체
- ar vr 차이
- rxjava hot observable
- 스택 큐 차이
- rxjava cold observable
- 스택 자바 코드
- 안드로이드 레트로핏 사용법
- ANR이란
- 2022 플러터 안드로이드 스튜디오
- 서비스 쓰레드 차이
- jvm이란
- 서비스 vs 쓰레드
- 플러터 설치 2022
- jvm 작동 원리
- 안드로이드 유닛 테스트 예시
- android retrofit login
- 안드로이드 레트로핏 crud
- 클래스
- 안드로이드 라이선스 종류
- Today
- Total
나만을 위한 블로그
[Android] ANR이란? 본문
ANR은 "Application Not Responding"의 약자로 번역하면 "애플리케이션이 응답하지 않음"이란 뜻이다.
간혹 상용 앱을 사용하거나 기능 구현 후 테스트하는 도중 마주치게 되는 문구인데, 안드로이드 디벨로퍼에서 말하는 ANR은 아래와 같다.
https://developer.android.com/topic/performance/vitals/anr?hl=ko
Android 앱의 UI 쓰레드가 너무 오랫동안 차단되면 ANR 오류가 발생한다. 앱이 포그라운드에 있으면 아래 그림과 같이 사용자에게 대화상자를 표시한다. 사용자가 ANR 대화상자에서 앱을 강제종료할 수 있다.
ANR은 UI 업데이트를 담당하는 앱의 기본 쓰레드가 사용자 입력 이벤트 또는 그림을 처리하지 못해 사용자 불만을 초래하므로 문제가 된다. 다음 조건 중 하나가 발생하면 앱 관련 ANR이 발생한다.
- 액티비티가 포그라운드에 있는 동안 앱이 입력 이벤트 또는 브로드캐스트 리시버(키 누름 또는 화면 터치 이벤트)에 5초 이내에 응답하지 못함
- 포그라운드에 액티비티가 없을 때 브로드캐스트 리시버가 상당한 시간 내에 실행을 완료하지 못함
위 글에서 말하는 그림이란 아래 이미지다.
결론은 메인 쓰레드가 일정 시간 동안 작업을 처리하지 못하면 발생하는 에러라는 뜻이다.
ANR의 발동 조건도 쓰여져 있지만 좀 더 정확한 발동 조건을 설명하는 곳은 없는지 찾아봤다.
https://itmining.tistory.com/3
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
시간이 많이 걸리는 작업은 서브 쓰레드에서 동작하게 해서 메인 쓰레드의 부하를 줄이면 된다
- 서브 쓰레드에서 시간이 오래 걸리는 작업을 수행하고 핸들러를 써서 작업 상태 메시지를 메인 쓰레드에 전달한다
- 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/
...(중략) 충돌은 처리되지 않은 앱 내 예외가 발생한 경우다. 예를 들어 EditText의 텍스트를 설정하려 하지만 EditText가 null이고 예외를 잡기 위한 try-catch 문이 없는 경우, 앱이 충돌하고 강제 종료될 수 있다. 사용자는 충돌의 원인을 볼 수 없으며 앱이 예기치 않게 강제 종료됐고 버그 보고서를 보낼 수 있다는 대화 상자가 표시된다.
메인 쓰레드에서 무거운 작업을 하지 말고 대신 IntentService, AsyncTask, Handler, 다른 쓰레드와 같은 워커 쓰레드를 사용해라. ANR이 발생하는 위치를 감지하는 것은 영구 블록(예 : 일부 잠금을 획득하는 교착 상태)인 경우 간단하지만 일시적인 지연인 경우 더 어렵다. 먼저 취약한 부분과 장기 실행 작업에 대해 코드와 모양을 재평가하라. 예에는 이벤트 쓰레드 안에서 소켓, 잠금, 쓰레드 절전 및 기타 차단 작업 사용이 포함될 수 있다. 이 모든 것이 별도의 쓰레드에서 발생하는지 확인해야 한다
결국 메인 쓰레드에서 수행하는 작업들이 너무 많으면 메인 쓰레드가 뻗어버리니까 적당히 쓰레드 만들어서 작업을 나눠 처리하게 하란 뜻이다. try-catch 문을 활용하는 것도 하나의 방법이라 한다.
'Android' 카테고리의 다른 글
[Android] 라이브러리 라이선스 종류와 특징 (0) | 2021.10.14 |
---|---|
[Android] 서비스 vs 쓰레드 (0) | 2021.10.14 |
[Android] 유닛 테스트란? 유닛 테스트 예시(JAVA) (0) | 2021.10.10 |
[Android] 안드로이드 OS의 구조 (0) | 2021.10.08 |
[Android] 인텐트란? (0) | 2021.10.07 |