메인 스레드의 한계
개발자가 별도의 작업 스레드를 만들지 않는 이상, 구현하는 모든 코드는 메인 스레드에서 동작한다. 그러나 아쉽게도 모든 작업을 메인 스레드에서 처리할 수는 없다.
안드로이드는 메인 스레드가 오랫동안 잠겨있는 것을 허용하지 않는다.
-> 5초 이상 메인 스레드가 잠기면 강제로 앱을 종료시키기 위한 팝업을 구동한다.(ANR 팝업)
메인 스레드와 스트릭트 모드
디스크에서 파일 읽고 쓰기, 네트워크 사용 -> 메인 스레드 사용 위반 사례(스트릭트 모드 위반)
권한 : 디바이스에서 보호된 기능이나 데이터를 접근하고 싶으면 퍼미션을 요청하고 승인을 받아야 한다.
사용자에게 퍼미션을 동의해줄 것을 요청한다.
런타임 권한 요청 방법
사용자가 권한에 대한 승인 또는 거절을 하게 되면 onRequestPermissionResult 함수가 호출됨!
override 해도되고 안해도 됨
긴 잡업을 실행하는 작업 스레드를 만들어서 처리하면 된다.
메인 스레드가 아닌 다른 스레드에서 화면에 그리는 작업을 허용하지 않는다.
제약사항이 존재하는 이유: 여러 스레드에서 각자의 뷰를 변경하여 화면을 갱신하게 된다면 동기화 문제가 발생할 수 있다. 그러므로 처리되는 순서가 불규칙한 스레드에서 그리는 작업을 하지 않게 안드로이드에서는 메인스레드에서만 그리는 작업을 허용한다.
이를 단일 스레드 GUI 모델이라 한다.
핸들러를 통해서 작업스레드에서 객체를 그리는 작업을 메인스레드로 넘길수 있다.
1. 메인 스레드가 생성된다.
2. 루퍼 객체를 생성하고, loop 함수를 실행함
3. 생성된 루퍼 객체는 내부적으로 메시지 큐 한개를 생성함
4. 루퍼는 loop 함수를 호출하여 무한 반복을 시작하고, 반복할 때 마다 메시지를 한개씩 추출함
5. 추출된 메시지를 처리한다.
1. 작업 스레드에서 Handler 객체 생성(개발자에 의해서)
2. Handler 객체는 메인 스레드의 루퍼 객체를 참조함
3. 작업 스레드는 메시지를 생성하고 실행 코드를 담는다.
4. Handler 객체를 이용하여 메인 스레드의 메시지 큐에 메시지를 넣는다.
*) 작업 스레드 뿐만 아니라 어디서든 핸들러를 생성하면 루퍼 객체를 참조한다.
메시지를 설정하는 두가지 방법
1. Runnable 객체로 메시지를 구성함.
2. Runnable 객체 대신에 메시지를 구성한느 변수들을 설정함. 메시지를 받아서 처리하는 handleMessage 함수를 재정의함. 이 함수는 루퍼가 실행시킨다.
Runnable 객체: 간단한 실행 코드를 추가하는 목적으로 사용
Handler handleMessage 구현: 메시지의 what 멤버변수로 구분하여 여러 가지 목적의 실행 코드를 한곳에서 모아 처리할 때 사용된다.
뷰의 post와 postDelayed 함수
액티비의 runOnUiThread 함수