Deperecated/Android_강의

안드로이드 - Handler를 통한 화면 처리

누알라리 2020. 2. 17. 23:11
1. 개요

1-1) 메인스레드

메인스레드는 애플리케이션 객체인 액티비티, 브로드캐스트 수신자 등과 새로 만들어지는 윈도우를 관리하기 위한 메세지 큐(Message Queue)를 실행한다.

1-2) 메세지 큐

순차적으로 코드를 수행하는 자료구조

1-3) 핸들러

메세지 큐를 이용해 메인 스레드에서 처리할 메세지를 전달하는 역할을 담당한다.

특정 메세지가 미래의 어떤 시점에 실행되도록 스케줄링을 할 수 있다.

 

출처:https://www.edwith.org/boostcourse-android/lecture/17086/

2. Handler를 통한 처리

2-1) obtainMessage() -> Intent와 비슷한 개념

- 호출의 결과로 메세지 객체를 리턴.

2-2) sendMessage()

- 메세지를 메세지 큐에 넣는다.

2-3) handleMessage()

- 메소드에 정의된 기능이 수행됨

- 코드가 수행되는 위치는 새로 만든 스레드가 아닌 메인스레드가된다.

 

3. Handler를 통한 화면 처리

- 안드로이드에서 네트워크에 관련된 처리나 5초 이상 걸리는 작업은 모두 개발자가 발생시킨 쓰레드에서 처리해야 한다.

- 개발자가 발생시킨 쓰레드에서 화면에 관한 처리를 하고자 할 때는 Handler를 이용해야 한다.

- 안드로이드 오레오(8.0)이상에서는 개발자가 발생시킨 쓰레드에서 화면처리를 해도된다.

 

4. Handler

- Thread에서 코드 처리 중 화면에 관련된 작업(UI 객체에 접근)이 필요하다면 Handler를 상속받은 클래스를 만들어 필요시 Handler를 요청하면 된다.

- Handler를 상속받은 클래스에 만든 메서드는 Main Thread에서 처리한다.

 

  1. 개발자가 발생시킨 쓰레드에서 화면 처리가 필요하다.
  2. Handler를 상속한 클래스를 만들어서 메소드를 오버라이딩.
  3. 개발자가 만든 Thread에서 Handler에 Message를 보내서 작업을 요청할 수 있다.
  4. 그래서 Handler에서 불린 Func은 MainThread에서 처리하게 된다.

 

class MainActivity : AppCompatActivity() {

    // 3. Activity가 종료되면 Thread도 종료될 수 있게 bool 변수 선언.
    var IsRunning:Boolean = false

    // 4. 개발자가 만든 쓰레드에서 화면처리 작업을 위해 Handler 생성
    var handler : DisplayHandler? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 1. 버튼을 누를 때 마다 현재 시간 textview에 출력
        button.setOnClickListener {  view ->
            var time = System.currentTimeMillis()
            textView.text = "버튼 클릭 : ${time}"
        }


        handler = DisplayHandler()

        // 2. Thread start
        IsRunning = true
        var thread = ThreadClass()
        thread.start()
    }

    // 2. Handler 사용을 위해 Thread 생성
    inner class ThreadClass : Thread()
    {
        override fun run() {

            while(IsRunning) {
                SystemClock.sleep(100)
                var time = System.currentTimeMillis()

                Log.d("test1", "쓰레드 : ${time}")
                //textView2.text = "Handler : ${time}"

                // 5. 개발자가 만든 Thread에서 Handler를 호출하게되면 MainThread가 한가할 때 작업 요청이 가능하다.

                // 5-1) 이 예제의 경우 Handler안에서 Time을 처리할 때는 걍 EmptyMessage만 보내도 된다.
                handler?.sendEmptyMessage(0)

                // 5-2) Message 객체에 여러개를 실어 보낼 수 있다.

                // Message.what = handler로 넘기는 작업의 Index개념.
                // Message.obj = 객체가 넘어가는것이기 때문에 Any 객체나 될 수 있다.
                var msg = Message()
                msg.what = 0
                msg.obj = time
                handler?.sendMessage(msg)
            }
        }
    }

    // 3. Activity가 종료되면 Thread도 종료될 수 있게 bool 변수 선언.
    override fun onDestroy() {
        super.onDestroy()

        IsRunning = false
    }

    // 4. 개발자가 만든 쓰레드에서 화면처리 작업을 위해 Handler 생성
    inner class DisplayHandler : Handler()
    {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)

            if(msg.what == 0) {

                // 5-1.
                //var time = System.currentTimeMillis()
                //textView2.text = " Handler : ${time}"

                // 5-2.
                textView2.text = "Handler : ${msg?.obj}"
            }
        }
    }
}