Handler class
- Handler는 Message를 MessageQueue에 넣는 기능과 MessageQueue에서 꺼내 처리하는 기능을 함께 제공한다.
Handler 생성자
- Handler에는 기본 생성자 외에도 Handler.Callback 이 전달되는 생성자도 있고, Looper가 전달되는 생성자도 있다.- Handler()
- Handler(Handler.Callback callback)
- Handler(Looper looper)
- Handler(Looper looper, Handler.Callback callback)
 
- 1~3번째 생성자는 파라미터 개수가 가장 많은 4번째 생성자를 다시 호출한다.
- 기본 생성자는 바로 생성자를 호출하는 스레드의 Looper를 사용하겠다는 의미이다.
- Handler 기본 생성자는 앱 프로세스가 시작할 때 ActivityThread에서 생성한 main Looper를 사용한다.
- Handler 기본 생성자는 UI작업을 할 때 많이 사용된다.
백그라운드 스레드에서 Handler 기본 생성자 사용하려면 Looper 필요
- 백그라운드 스레드에서 Handler 기본 생성자를 사용했을때 Looper가 준비되어 있지 않으면 RuntimeException이 발생 
- 이를 해결하기 위해서 Looper.prepare()를 실행해서 해당 스레드에사 사용할 Looper를 준비해야 한다. 
- 내부적으로 prepare() 메서드는 MessageQueue를 생성하는 것 외에 별다른 동작을 하지 않는다. 
- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - class LooperThread extends Thread{ public Handler mHandler; public void run(){ Looper.prepare(); mHandler = new Handler(){ public void handleMessage(Message msg){ // 여기서 Message 처리 } }; Looper.loop(); } } 
- LooperThread에서 스레드를 시작하면 Looper.loop()에 무한 반복문이 있기 때문에 해당 스레드는 종료되지 않는다. 그리고 mHandler에서 sendXxx(), postXxx()메서드를 사용하면 스레드내에서 handleMessage를 실행한다.
호출 위치가 메인 스레드인지 확인이 쉽지 않음
- 백그라운드 스레드에서 Handler 기본 생성자를 쓴 경우 Looper가 준비되지 않아 RuntimeException을 만나는 경우가 있다.
- 백그라운드에서 Looper를 생성해도 UI를 업데이트하는 작업을 하면 CalledFromWrongThreadException이 발생하게 된다. 이를 해결하기 위해서는 Handler의 세 번째 생성자인 Handler(Looper looper)를 사용하면된다.
- 1 2 3 4 5 6 7 8 - public void process(BadgeListener listener){ int count = ... new Handler(Looper.getMainLooper()).post(new Runnable(){ public void run(){ listener.updateBadgeCount(count); } }); } 
- Handler 생성자에 Looper.getMainLooper()를 전달하면, 메인 Looper의 Message Queue에서 Runnable Message를 처리한다.le Message를 처리한다.
