Uing? Uing!!

[내 맘대로 정리한 안드로이드] 왜 UI Thread에서는 긴 작업을 하면 안 되는 걸까? 본문

Android

[내 맘대로 정리한 안드로이드] 왜 UI Thread에서는 긴 작업을 하면 안 되는 걸까?

Uing!! 2020. 7. 30. 05:47
반응형

Main Thread (UI Thread)와 Worker Thread

안드로이드에는 Main Thread (UI Thraed)와 Worker Thread라는 개념이 따로 존재한다.

이름만 다른 것이 아니라, 두 종류의 Thread는 아예 다른 목적으로 사용된다.

 

Main Thread는 어플리케이션을 실행하면 기본적으로 작업이 실행되는 스레드이고,

Worker Thread는 특정한 목적을 위해 따로 생성해서 동작하는 스레드이다.

 

Main Thread와 Worker Thread를 사용하는 규칙은 단순하게 아래 두 가지이다.

 

1. Main Thread에서는 긴 시간이 걸리는 작업을 지양해야 한다.

2. Worker Thread에서는 UI 작업을 하지 않아야 한다.

 

이렇게만 적혀 있으면 당연히 궁금해진다. 

왜...?

왜 이 두 가지를 지켜야 하는가?

각각의 규칙을 무시한다면 어떤 일이 일어나는가?

 

Q. Main Thread에서 긴 작업을 하면 어떻게 되는가?

Main Thread (UI Thread)는 화면의 UI를 업데이트하는 작업이 진행되는 스레드이다.

하지만 이 스레드는 단일 스레드이기 때문에, 주어지는 작업들이 순차적으로 진행된다.

 

화면이 나타나야 하는데, 화면을 업데이트하기 직전에 60초짜리 이미지처리 작업이 끼어들었다고 생각해 보자.

UI Thread는 먼저 들어온 작업을 다 처리하고 다음 작업을 처리해야 하므로 우선 60초짜리 작업을 하고 화면을 설정하게 된다.

그렇다면 우리의 어플리케이션 화면은 60초동안 응답하지 않는 상태가 되는 것이다.

 

일단 화면이 멈춰 버린다. 그리고 몇 초가 흐른다. 마침내 화면에는 '응답 없음' 팝업이 뜬다.

팝업을 무시하면 60초 뒤에 화면은 무사히 로딩될 것이다.

하지만 그렇다고 '응답 없음' 에러 메시지를 띄우는 앱을 런칭할 수는 없다.

으악! (각색된 경험담입니다.)

 

반면 Worker Thread를 따로 만들어 60초짜리 작업을 시키게 되면,

UI Thread는 Worker Thread가 열심히 작업하는 동안 무사히 화면 상태를 유지할 수 있다.

네트워크 작업의 경우

이미지처리의 경우에는 위와 같지만, 사실 네트워크 작업의 경우에는 이런 문제가 발생하기 어렵다.

애초에 API 11부터는 네트워크와 통신하는 작업 등은 Main Thread에서 작업이 불가능하도록 되어 있기 때문이다.

 

Q. Worker Thread에서 직접 UI작업을 하면 어떻게 되는가?

한 프로세스 내에 Main Thread (UI Thread)는 하나이지만, Worker Thread는 여러개일 수 있다.

Main Thread와 Worker Thread가 동시에 UI 작업을 수행하고 있다고 가정하자.

어느 순간 두 스레드가 같은 UI자원에 접근해서 서로 다른 수정을 요구한다면 수행해야 할 작업이 모호해진다.

 

이런 현상을 방지하기 위해서 안드로이드에서는 Main Thread에서만 UI작업을 진행할 것을 요구한다.

사실 애시당초 Worker Thread에서 UI작업을 직접 하려고 시도하면 안드로이드에서 에러를 발생시키기 때문에,

2번 규칙을 무시하고 작업하게 되는 일을 흔하지 않을 것 같다.

 

Q. Worker Thread에서 UI를 수정하고 싶다면 어떻게 해야 하는가?

하지만 당연하게도, Worker Thread에서의 작업 결과를 UI에 반영해야 하는 상황이 있을 수 있다.

예를 들면 서버에서 100장의 이미지를 받아오면서 하나씩 화면에 표시하는 작업이라든가.

 

이미지를 받아오는 것은 네트워크 작업에 해당하기 때문에 Main Thread에서 수행할 수 없다.

하지만 Worker Thread에서 작업을 하게 되면 직접적으로 UI를 수정할 수 없다.

그렇다면 이런 경우에는 어떻게 작업을 해야 하는가?

이럴 때에는 Handler를 사용할 수 있다.

Handler는 '핸들러가 생성된 스레드'에서의 작업을 순차적으로 처리해 준다. 따라서,

 

1) Main Thread에서 Handler 객체를 생성해 주고

2) Worker Thread에서 필요한 위치에서 위의 Handler 객체를 꺼내 와서

3) Handler의 post나 sendMessage 메소드 등으로 UI 변경을 요청할 수 있다.

 

와 같은 방식으로 Main Thread에 화면 변경 요청을 전달할 수 있다.

이에 대한 자세한 내용은 추후에 다룰 기회가 있을 것 같다.

 

반응형
Comments