⚙️ 안드로이드 Thread와 Handler 2

안녕하세요 :) 오늘은 MessageQueue 의 작업 대상인 MessageRunnable 에 대해 공부하고, 이 시리즈의 꽃인 Handler에 대해 설명해보려 합니다. 이전 게시물과 연계되는 지식이 왕왕 요구되므로, 참고하시면서 이해하시길 바랍니다. 오늘도 화이팅 입니다 ! 🌿

1️⃣ Message


Message 란 ?

  • Message는 java.lang.Object의 android.os.Message에 위치한 클래스입니다.
  • Message는 간단하게 말하자면, 정보들의 모음입니다. Message를 정의한다는 것은 핸들러에게 보내질 수 있는 임의의 정보와 설명을 정의한다는 것 입니다. 여기서 핸들러에게 보내질 수 있어야한다는 말은, 핸들러가 스레드간의 통신 매개로서, 다른 스레드에서 실행될 작업에 대한 정보를 전달할 수 있어야한다는 말입니다.
  • 앞서 말씀드린 Message 정보들은 Message의 public 변수로 설명할 수 있습니다. (메세지 구성 요소)

메세지를 생성 방법

  • Message의 public 생성자를 사용하여 객체를 생성할 수는 있지만, Message 객체는 Message.obtain() 이나 Handler.obtainMessage()을 통해 얻고 관리되어야합니다.

    While the constructor of Message is public, the best way to get one of these is to call Message.obtain() or one of the Handler.obtainMessage() methods, which will pull them from a pool of recycled objects.

  • 사용된 Message 객체들은 Looper.loop()에서, recycleUnchecked()를 통해 재사용할 수 있게 초기화됩니다. 만약 obtain()으로 관리 되지 않는다면, 재사용될 Message들이 불필요하게 많이 생기게 되고, 이는 pool을 금방 꽉차게 만들어 자원을 낭비하게 됩니다.

2️⃣ Runnable


Runnable 란 ?

  • Runnable은 java.lang.Runnable에 위치한 인터페이스입니다.

  • Runnable 인터페이스의 구현 클래스는 run이라는 추상 메서드를 구현해야합니다.

    • public interface Runnable {
          /**
           * When an object implementing interface <code>Runnable</code> is used
           * to create a thread, starting the thread causes the object's
           * <code>run</code> method to be called in that separately executing
           * thread.
           * <p>
           * The general contract of the method <code>run</code> is that it may
           * take any action whatsoever.
           *
           * @see     java.lang.Thread#run()
           */
          public abstract void run();
      }
  • 즉 구현된 run()에 있는 명령어들, 즉 실행될 코드 그 자체를 객체로 저장하고 있는 형태가 Runnable이라 생각하시면 쉽습니다. 따라서 Runnble의 매개변수명을 target이라 부르기도 합니다.

  • Runnable 인터페이스의 구현 클래스의 구현 객체는 스레드에서 실행되어야합니다. 구현된 Runnable은, 해당 Runnable을 사용하는 스레드에서, 구현된 run()의 정의대로 실행됩니다. 즉, 스레드가 시작되면, Runnable의 run()이 호출됩니다.

    The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.

    the object whose run method is invoked when this thread is started. If null, this classes run method does nothing.

  • Runnable의 구현 클래스는 Thread를 subclassing하지 않아도 run()을 통해 동작될 수 있게 합니다. 앞서 말씀드린 스레드 정의 방법 중 Runnable 인터페이스를 구현하여 스레드를 구현할 수 있는 이유입니다. (이 특성으로 인해, 자바의 다중 상속 불가 문제를 해결합니다.)

    • run()을 통해 동작될 수 있다는 말이, Runnable이 run()을 실행시킨다는 말이 아닙니다. Runnable은 단순히 run()을 제공하는 인터페이스일 뿐, 실행은 생성된 스레드가 이 run()을 호출시켜 이뤄지는 것입니다. run()이 스레드를 실행하는 것이 아니라는 점을 강조하겠습니다.

    subclassing은 부모를 상속 받거나, 부모를 상속받고 자신 고유 특성을 추가하는 것을 의미합니다. 예를 들면, 확장 없이 부모를 그대로 상속 받는 것도, 부모의 메서드를 오버라이딩 하는 것도 subclassing 입니다.

    A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target.

  • 개발자의 특수 목적이 없는 이상, Runnable 구현 클래스는 run() 메서드만 오버라이딩하여 사용해야한다고 합니다.

    In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

잠깐! 그럼 Runnable은 Looper의 없이 동작할 수 있나요?

  • 네 그렇습니다. Runnable은 기본적으로 Thread의 실행부 역할로 동작합니다. Looper를 기본적으로 생성하지 않는, 일반 Thread 클래스로 생성된 스레드는 run()만 실행한 후 종료합니다. Looper와 관계되는 이유는 MessageQueue에 Message뿐만 아니라 Runnable도 enqueue되어 사용될 수 있다는 점 때문입니다.

#️⃣ Reference


좋은 웹페이지 즐겨찾기