코딩하는 개굴이

[안드로이드] View 의 조작과 MainThread(UI Thread) 본문

안드로이드

[안드로이드] View 의 조작과 MainThread(UI Thread)

개굴이모자 2023. 3. 5. 21:42
반응형

Android 에서 비동기 실행을 할때 본인은 간혹 실수하여 에러를 마주하곤 한다.

바로 View 를 UI Thread 에서 변경하지 않아서 발생하는 것이 그것이다.

안드로이드 시스템은 애플리케이션이 실행되면 하나의 실행 스레드로 애플리케이션의 프로세스를 실행하는데, 이것을 메인 스레드라고 한다.

UI 도구 키트 구성 요소를 생성 및 조작할 때 상호작용하는 스레드가 MainThread 이며, 그렇기 때문에 UI Thread 라고도 불린다.

 

Main Thread 에서는 오래 소요되는 작업을 수행하지 않는 것을 권장하는데, 오래 소요되어 응답성/반응성이 떨어진다면 사용성이 떨어지거나 ANR 이 발생할 수 있기 때문이다.

 

따라서, 안드로이드 스레드 사용 시 아래와 같은 사항을 유념해야한다.

  1. 시간이 오래걸리는 작업은 UI 스레드로부터 분리하고, 별도의 스레드에서 실행하여 UI 스레드 작업이 지연/차단되는 것을 방지해야한다.
  1. UI 스레드가 아닌 스레드에서 UI component 를 조작할 수 없다.

 

 

그렇다면 불가피하게 메인 스레드가 아닌 스레드의 결과에 따라 UI 를 변경해주어야하는 경우에는 어찌 처리되어야하는가?

 

Activity.runOnUiThread(Runnable r)

Developers 가이드에는 해당 메서드에 대해 이렇게 설명하고 있다.

“특정 동작을 UI 스레드에서 동작하도록 한다. 만약 현재 스레드가 UI 스레드이면 그 동작은 즉시 수행되고, 그렇지 않으면 필요한 동작을 UI 스레드의 이벤트 큐로 전달한다.”

 

해당 메서드의 구현부를 살펴보면, Handler 를 이용해 runnable 을 전달한다. (UI Thread에 Queue 의 형태로 enqueue 된다.)

 

startActivity 를 통해서 생성되는 ActivityThread 는 UI thread Looper와 Handler를 생성하는데 loop 을 돌면서 전달된 runnable 을 처리한다.

 

 

문제점! 만일 종료가 되면…?

여기서 한번 더 나아가보자.

runOnUiThread 를 다운로드 혹은 Request 의 결과가 success이면 수행하는 로직이 있다고 가정했을 때, 만일 어떠한 연유로 크래시가 나면 전달된 runnable 은 어찌될까?

 

thread 객체를 만들고 start 하면 다른 스레드가 실행되므로, onDestroy 를 해도 다른 스레드는 중지되지 않고 main thread 에서 이를 강제 중지할 수는 없다. 따라서, onDestroy 에서 프로그램을 안전하게 종료할 수 있도록 해야하는 등 스레드 관리에 별도의 작업이 필요하다.

 

그 외

이렇게 스레드를 관리하는 것은 보일러 플레이트 코드(반복적으로 비슷한 형태를 띄는 코드)들을 유발하고 복잡하게 한다.

 

따라서, RxJava 나 Corouine 등을 사용하여 편리하게 구현하는 것을 권장한다.

 

+) 본래, AsyncTask 를 이용한 방법이 제공되었으나, 이는 deprecated 되었다.

 

참고 링크


Uploaded by

N2T
반응형
Comments