Handler
메인 액티비티는 앱이 실행될 때 하나의 프로세스에서 처리된다
하지만 같은 프로세스 안에서 여러 기능들이 순서대로 실행될 때 대기 시간이 길어지는 네트워크 요청 등의 기능을 수행할 때는 화면에 보이는 UI도 멈춰져 있는 상태로 보이는 문제가 존재합니다.
이러한 문제를 해결하기 위해서 하나의 프로세스 안에서 여러 개의 작업이 수행되는 멀티 스레드 방식이 존재한다.
하지만 여러 스레드들이 동시에 리소스를 접근하려고 할때는 데드락이 발생할 수 있다. 데드락이 발생하면 시스템이 비정상적으로 동작하게 된다.
따라서 네트워크 요청 등과 같은 지연 시간이 길어질 수 있는 작업들은 따로 분리하여 UI에 응답을 보내는 방식을 사용할수 있게 해주는것이 Handler 이다.
안드로이드에서 UI 작업은 별도의 스레드(이하 워커 스레드(worker thread))가 아닌 메인스레드에서 작업을 해야한다.
그러면 워커 쓰레드 내에서 UI 작업을 해주어야 할때는 어떻게 해야 할까?
이때 해당 스레드와 메인 스레드를 이어주는 것이 핸들러이다.
핸들러의 역할은 간단하게 말하면 메시지를 전달하는 것이다.
워커 스레드에서 핸들러는 메인 스레드로 메시지를 전달하게 된다.
그러면 그 메시지를 수신한 메인스레드에서 적절한 UI 작업을 처리하게 되는 것이다.
안드로이드는 메인 스레드에서 UI작업을 처리하게 된다, 그런데 만약 메인 스레드에서 UI 작업이외에 시간이 많이 걸리는 작업을 하게 된다면 UI 처리가 늦게 이루어진다. UI 처리가 늦게 이루어지면 반응성이 떨어지게 되고 사용자는 답답함을 느낄 수 있다. 따라서 시간이 오래걸리는 작업을 메인 스레드에서 작업을 시키면 안된다.
그러면 이제 핸들러가 어떤식으로 스레드간 통신을 하는지 알아보자.
먼저 수신 받을 스레드에서 핸들러 객체를 생성해주고 handleMessage()를 오버라이딩해서 메시지를 받을때 어떤 동작을 수행 할것인지 작성한다. 그러면 워커 스레드에서 해당하는 핸들러 객체에 메세지 객체를 인자로 넣고 sendMessage메소드를 통해 핸들러로 전달한다. 그러면 수신 받은 쓰레드에서는 그 받은 메시지를 메시지 큐에 이동시키고 루퍼는 메시지큐에 루프를 돌면서 먼저들어간 메시지를 빼서 핸들러로 전달하게 된다. 그러면 이제 전달받은 메시지 객체를 이용한 핸들메시지 매소드가 동작하게 된다.
근데 이렇게 핸들러와 메시지말고 핸들러와 Runnable객체를 통해서도 스레드간 통신을 할 수 있다. 기존에 핸들러와 메시지를 통해서 스레드간 통신을 했을때는 메시지에 저장된 데이터의 종류를 식별하기 위해서 메시지에 포함된 what값을 상수로 정의하고 handleMessage()에서 해당된 상수에 맞는 조건문을 통해 코드를 실행하는 경우가 있다. 그리고 송신을 하는 스레드 입장에서도 전달할 데이터의 종류에 따라서 별도의 메시지 객체를 만들어 그에 해당되는 값들을 채워넣어서 수신 받을 스레드에 전달해야한다.
하지만 우리가 스레드간 통신을 할때 수신받을 스레드에 작성된 코드를 실행하는것이 주 목적이라면 굳이 메시지를 통해 데이터를 전달하지 않고 바로 실행코드를 Runnable 객체에 포함시켜 수신 스레드로 전달시켜서 Runnable 객체에 포함된 코드를 실행시키면 필요없는 메시지를 만들지 않고도 원하는 코드를 실행시킬 수 있다.
이러한 핸들러와 Runnable객체를 통한 스레드간 통신을 만드는 방법은 수신 받을 스레드에서 handleMessage()를 구현하는것이 아니라 송신 하는 쓰레드에서 Runnable 객체를 만들고 run()메소드를 오버라이딩 함으로써 핸들러 객체에 .post()에 인자를 Runnable 객체로 넣음으로써 송신받을 핸들러로 Runnable 객체를 메시지로써 전달한다. 이렇게 하면 실행할 코드를 바로 전달하면서 수신 받을 스레드에서 내가 원하는 코드로 작업을 진행 할 수 있다.
'안드로이드(Kotlin)' 카테고리의 다른 글
Kotlin 코틀린의 SharedPreferences (0) | 2022.08.08 |
---|---|
Kotlin 코틀린의 Context (0) | 2022.08.08 |
Kotlin 코틀린의 Intent와 Inflate (0) | 2022.08.04 |
Kotlin 코틀린의 Layout (0) | 2022.08.04 |
Kotlin 코틀린의 Lifecycle (0) | 2022.08.03 |