2011-07-02 4 views
4

다른 스레드에서 메인 스레드의 메시지 대기열을 얻으려면 어떻게해야합니까? Looper.getMainLooper()는 주 스레드의 루퍼를 가져 오지만 다른 스레드의 루퍼에 대한 MessageQueue를 가져 오는 방법을 찾을 수 없습니다. 게다가, 어떻게 주 루퍼의 처리기를 얻을 수 있습니까? 나는 그것을 얻을 어떤 방법을 찾을 수 없습니다.메인 스레드의 메시지 대기열 및 처리기를 얻습니다.

+0

왜? 대기열을 직접 처리 할 필요가 없습니다. – CommonsWare

+0

메인 스레드가 뭔가를하고 있는지 확인하기 위해 idleHandler를 추가하고 싶습니다. –

+0

@CommonsWare 어떻게 든 메인 스레드의 메시지 큐가 비어 있는지 확인하고 싶습니다. 나는이 개념을 처음 접했고 큐가 비게 될 때 알림을 받기 위해 idleHandler를 사용하려고 생각했다. –

답변

0

메인 스레드 루퍼를 얻은 후에는 메인 스레드 인 MessageQueue를 얻기 위해 myQueue를 호출 할 수 있어야합니다. 나는 비슷한 필요를했다

r.v @

http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29

+0

설명서에 현재 스레드의 MessageQueue가 반환되며 주 스레드와 다른 스레드에서 가져 오려고한다고 나와 있습니다. –

+0

죄송합니다. 질문을 잘못 읽었습니다. MessageQueue는 내부 구조이므로 안드로이드가 스레드 외부에서 직접 액세스 할 수 있는지 여부는 확실하지 않습니다. 주 스레드의 처리기와 루퍼를 사용하여 수행 할 수없는 MessageQueue를 사용하여 무엇을하고 싶습니까? – RAnderson

+0

주 스레드가 아무것도하지 않는지 확인하기 위해 idleHandler를 추가하려고합니다. 그건 그렇고, 또한 메인 스레드에 대한 처리기가 필요 - 내 질문에 대한 편집했습니다. –

3

. MessageQueue가 비어있는시기를 알기 원했고, 할 일을 게시 할 때 남은 것이 아무것도없는 상태에서 비어있는시기를 알고 싶습니다. 나는 MessageQueue.IdleHandler을보고 다른 솔루션을 생각해 내고 싶지 않았기 때문에 동작하지 않는 것으로 나타났습니다.

내 경우에는 파일 다운로드를 순차적으로 실행하기 위해 루퍼/핸들러 메커니즘을 사용하고 싶었습니다. 기본적으로 실행하려는 각 다운로드는 Runnable에 래핑됩니다. 한 번에 하나씩 만 실행하고 싶기 때문에이 패턴은보다 복잡한 스레딩 솔루션의 핵심을 파고 들지 않고도 잘 작동합니다. 또한, 큐에 처음 넣은 것을 알고 싶습니다. 큐가 비어있는 시점을 알고 싶었습니다.

이것을 달성하기 위해 핸들러의 메시지 메커니즘을 사용할 수있었습니다. 메시지는 Runnables와 차례대로 처리되므로 메시지를 큐에 전략적으로 배치하여 큐의 상태를 알 수 있습니다. Handler의 대기열에있는 Runnables와는 달리, 궁극적으로 해결책을 제공하는 메시지에 대해 몇 가지 쿼리 및 제거 기능이 있습니다.

핸드북에 실행 파일을 추가 할 때마다 (Handler.post 통해) 사용자 정의 QUEUE_EMPTY 메시지의 인스턴스를 모두 제거한 다음 신선한 QUEUE_EMPTY 메시지를 추가합니다. 이렇게하면 대기열 끝에 QUEUE_EMPTY 메시지가 있습니다. 서브 클래 싱 된 Handler에서 QUEUE_EMPTY 메시지가 발생하면 대기열의 끝에 있음을 알게됩니다. 또한 실행 파일을 추가 할 때 큐에 QUEUE_EMPTY 메시지가 없으면 큐가 비어 있고 스레드가 유휴 상태라는 것을 알고 있습니다.

일부 사용자는이 솔루션을 사용하면 실제로 비효율적 인 부분이 있음을 쉽게 알 수 있습니다. 대기열에 많은 수의 항목이있는 경우 이러한 "마커"메시지에 대한 대기열을 반복하는 것이 실제 성능 문제 일 수 있습니다. 필자는 한 번에 소수의 파일 다운로드 만 처리하므로 모든 성능 저하는 무시할 수 있습니다. 비슷한 상황에 처한 경우 이것이 합리적인 해결책이라고 생각합니다. Android SDK가 MessageQueue에 이러한 기본 기능을 제공하는 것이 좋을 것입니다. MessageQueue를 엉망으로 만들고 싶지는 않지만, 유휴/작업/빈 상태가 합리적인 것처럼 보이는 것이 이상적이며, 이러한 것들을 알고있는 가치가있을 때는 많은 시나리오가 있다고 확신합니다.

class DownloaderThread extends Thread 
{ 
    private static final int QUEUE_EMPTY = 9999; 
    private MyHandler handler; 

    @Override 
    public void run() 
    { 
     try 
     { 
      Looper.prepare(); 
      handler = new MyHandler(); 
      Looper.loop(); 
     } 
     catch (Throwable t) 
     { 
      Log.e(TAG, "halted due to an error", t); 
     } 
    } 

    public void post(Runnable r) 
    { 
     if(!handler.hasMessages(QUEUE_EMPTY)) 
     { 
      Log.v(TAG, "Download queue was empty. First element being added."); 
     } 

     handler.post(r); 
     handler.removeMessages(QUEUE_EMPTY); 
     handler.sendEmptyMessage(QUEUE_EMPTY); 
    } 

    class MyHandler extends Handler 
    { 
     @Override 
     public void handleMessage(Message msg) 
     { 
      if(msg.what == QUEUE_EMPTY) 
      { 
       Log.v(TAG, "Download runnable queue is empty!"); 
      } 
     } 
    } 
}; 
1

루퍼의 메시지 큐와 상호 작용하기 위해 Handler 클래스를 사용하십시오.

Handler mainHandler = new Handler(Looper.getMainLooper(), new Callback() { 

     @Override 
     public boolean handleMessage(Message msg) { 
      // TODO Auto-generated method stub 
      return false; 
     } 
    }); 
mainHandler.post(...); 
mainHandler.sendMessage(...); 
mainHandler.removeMessage(...); 

지금 보낼 수 있으며, 주요 스레드의 메시지 큐와 상호 작용 메시지를 제거하고받을 수 있습니다.

관련 문제