안녕하세요 :) 오늘은 MessageQueue 의 작업 대상인 Message 와 Runnable 에 대해 공부하고, 이 시리즈의 꽃인 Handler에 대해 설명해보려 합니다. 이전 게시물과 연계되는 지식이 왕왕 요구되므로, 참고하시면서 이해하시길 바랍니다. 오늘도 화이팅 입니다 ! 🌿
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 theHandler.obtainMessage()
methods, which will pull them from a pool of recycled objects.
사용된 Message 객체들은 Looper.loop()에서, recycleUnchecked()를 통해 재사용할 수 있게 초기화됩니다. 만약 obtain()으로 관리 되지 않는다면, 재사용될 Message들이 불필요하게 많이 생기게 되고, 이는 pool을 금방 꽉차게 만들어 자원을 낭비하게 됩니다.
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. Ifnull
, this classesrun
method does nothing.
Runnable의 구현 클래스는 Thread를 subclassing하지 않아도 run()을 통해 동작될 수 있게 합니다. 앞서 말씀드린 스레드 정의 방법 중 Runnable 인터페이스를 구현하여 스레드를 구현할 수 있는 이유입니다. (이 특성으로 인해, 자바의 다중 상속 불가 문제를 해결합니다.)
subclassing은 부모를 상속 받거나, 부모를 상속받고 자신 고유 특성을 추가하는 것을 의미합니다. 예를 들면, 확장 없이 부모를 그대로 상속 받는 것도, 부모의 메서드를 오버라이딩 하는 것도 subclassing 입니다.
A class that implements
Runnable
can run without subclassingThread
by instantiating aThread
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 therun()
method and no otherThread
methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.