2013-03-21 3 views
5

다른 스레드의 동일한 루퍼에서 수신하는 핸들러를 구현하려고합니다.Looper.getMainLooper()로 초기화 된 핸들러가 메시지 콜백에 응답하지 않습니다.

아래에는 두 개의 핸들러가 있습니다. 하나는 메인 스레드에서 생성되고 다른 하나는 자식 스레드에서 생성되지만 둘 다 Main Looper에서 수신 대기하도록 초기화됩니다.

private Handler mMain; 
public static final ThreadPoolExecutor tpe = 
     (ThreadPoolExecutor) Executors.newCachedThreadPool(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mMain = new Handler(Looper.getMainLooper()) { 
     @Override 
     public void handleMessage(Message msg) { 
      Log.wtf("", "main:" + msg); 
     } 
    }; 

    tpe.execute(new Runnable() { 
     private Handler tChild = new Handler(Looper.getMainLooper()) { 
      @Override 
      public void handleMessage(Message msg) { 
       Log.wtf("", "child:" + msg); 
      } 
     }; 

     @Override 
     public void run() { 
      Log.wtf("", "send msg to main looper"); 
      tChild.sendEmptyMessage(100); 
     } 
    }); 
} 

그러나 아래와 같은 메시지를 보내면 하위 처리기 만 메시지를 인쇄합니다. 주 처리기가 메시지를받지 못합니다.

03-20 22:02:26.754: A/(12857): send msg to main looper 
03-20 22:02:26.847: A/(12857): child:{ what=100 when=-8ms } 

내가 뭘 잘못하고 있니? 읽어 주셔서 감사합니다.

답변

10

Handler 인스턴스는 대상을 제어하며 공유 할 수있는 방법이 없으므로 Handler으로 보낸 모든 메시지 또는 게시물은 해당 인스턴스에서만 실행됩니다.

Looper은 메시지/실행 파일이 실행될 을 나타냅니다. 코드에서 두 핸들러는 별도의 스레드에서 작성 되었음에도 불구하고 주 스레드에서 handleMessage()을 실행합니다. 즉, 작업 ... HandlerLooper 인스턴스를 전달 더 Looper다음Handler이가 작성된 스레드에서 코드를 실행하지 않습니다 전달하는 경우 (해야 또한 Looper 스레드 수) 수있는 진짜 이유입니다 .

이 때문에 데이터를 게시하는 데 여러 Handler를 만들 필요가 없습니다. 단일 Handler은 여러 스레드에서 메시지를 보내도록 설계되었으며 모두 MessageQueue에 직렬화되고 선택한 Looper 스레드에서 실행됩니다. 해당 스레드에서 코드를 실행하려면 백그라운드 스레드에서 mMain에 직접 게시 할 수 있습니다. 이 경우 Looper을 전달하는 코드는 이미 메인 스레드에 있습니다.

+0

감사합니다. 언젠가 Runnable이 내부 클래스가 아닌 외부 클래스라면, 초기화 된 핸들러를 생성자를 통해 전달해야한다고 가정 해 봅시다. 맞습니까? –

+0

아키텍처는 애플리케이션에 따라 다르지만 메시지를 게시하려는 곳이면 어디에서나 'Handler'에 대한 참조가 필요합니다. – Devunwired

+0

왜 응용 프로그램 컨텍스트 (응용 프로그램을 확장하는 클래스)에서 하나의 Handler (this.getMainLooper())를 사용하지 않는 것이 좋을까요? 이것은 활동에서 그것을하는 것보다 깨끗하지 않습니까? –

1

Handler으로 보낸 메일은 Looper을 공유하고 있어도 Handler으로 만 처리됩니다. 핸들러의 소스 코드에 묻혀

라인이 그것을 만질 다른 Handler 보장하지

msg.target = this; 

입니다.

관련 문제