Posts 메인 스레드와 Handler - (2)
Post
Cancel

메인 스레드와 Handler - (2)

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를 처리한다.
This post is licensed under CC BY 4.0 by the author.

메인 스레드와 Handler - (1)

메인 스레드와 Handler - (3)

Comments powered by Disqus.