2010-02-18 3 views
4

두 개의 스레드 (메인 및 데이터 로더)가있는 앱이 있습니다. 데이터 로더가 끝나면 (DevGuide에서 설명한대로) 주 스레드에 Runnable 객체를 게시하지만 결코 전달되고 실행되지 않습니다. 핸들러가 기본 스레드에 메시지 또는 Runnable을 전달하지 못했습니다.

class MyApp extends Application 
{ 
    public void onCreate() 
    { 
     LoaderThread t = new LoaderThread(); 
     t.start(); 
    } 

    private class LoaderThread extends Thread 
    { 
     public void run() 
     { 
      SystemClock.sleep(2000); 
      boolean res = m_handler.post(m_runnable); 
      if(res) 
       Log.d(TAG, "Posted Runnable"); 
     } 
    } 

    private final Handler m_handler = new Handler(); 
    private final Runnable m_runnable = new Runnable() { 
      public void run() 
      { 
       Log.d(TAG, "Hey, i'm runnable!"); 
      } 
     } 
} 

은 또한 그것은 어쩌면 중요한 내가 ApplicationTestCase에서 파생 된 단위 테스트로이 코드를 실행 유의하기 :

class MyAppTest : public ApplicationTestCase 
{ 
    public MyAppTest() 
    { 
      super(MyApp.class); 
    } 

    public void testLoading() 
    { 
      createApplication(); 
      // few asserts follow here... 
    } 
} 

그래서이 실패

는 여기에 기본 코드입니다. Runnable은 run() 호출을받지 못한다. 로그는 성공적으로 게시되었음을 나타낸다. 또한 runnable (예를 들어 m_handler.sendEmptyMessage (1))을 게시하는 대신 간단한 메시지를 보내려고했습니다. 메인 스레드의 핸들러 콜백에 전달되지 않습니다.

무엇이 여기에 있습니까? 사전 :

답변

1

Handler은 작동하려면 Looper이 필요합니다. LooperHandler에 필요한 메시지 큐를 제공합니다.

Activity의 모든 인스턴스는 UI 이벤트를 처리하는 데 사용되므로 이 있지만 다른 인스턴스 인 Looper을 만들 수 있습니다.

로그 출력에서 ​​Looper이 없음에 대한 Android의 불만 여부를 확인하십시오. 이 경우

, 당신은 당신의 onCreate() 방법의 상단에 따라 수정 추가 할 수 있습니다

Looper.prepare(); 
m_handler = new Handler(); 
Looper.run(); 

그리고 나중에 코드에서에서 m_handler의 초기화를 제거합니다.

+0

나는 그렇게 생각했지만 루퍼는 정말로 만들어졌습니다. 왜냐하면 내가 직접 (위의 제안을 시도하는 것을 포함하여) 만들려고 할 때 : "java.lang.RuntimeException : 하나의 루퍼가 스레드 당 하나만 생성 될 수 있습니다" 또한 코드가 변경되지 않았다는 것을 알았습니다. 운영 체제에서 완전히 날아간 응용 프로그램을 실행했을 때 좋았습니다. 반면에 테스트 케이스로 실행하면 작동하지 않습니다 ... 힌트 : 루퍼는 괜찮습니다. null이 아니며 예외도없고 로그에 오류가 없습니다. 나는 당혹 스럽다. – dimsuz

+0

힌트를 보내 주셔서 감사합니다! 내 코드는 Activity 내에서가 아니기 때문에 루퍼 내에 없습니다. 나는 핸들러를 통해 보낸 메시지가 호출 스레드가 중단되었을 때만 전달되는 이유를 알아 내려고했습니다. – Sney

0

Handler에서

덕분에 만 Activity AFAIK에서 작동합니다. Application에서 사용하려고합니다.

+0

난 그냥 테스트로 실행하면 바로이 코드는 OS에서 응용 프로그램으로 실행할 때 작동하지만, 실패하는 것을 발견 ... 그래서 나는이 뭔가 빠진 것 같다. 어쩌면 활동과 관련이 있습니다 ... – dimsuz

0

Looper.prepare()으로 전화하는 대신 new Handler(Looper.getMainLooper())으로 전화하는 것입니다. Looper.prepare()을 호출 할 때의 문제점은 스레드에 이미 루퍼가있는 경우 예외가 발생한다는 것입니다. 여러 환경에서 실행해야하는 코드를 작성할 가능성이 있으며이 솔루션은 더 많은 경우를 처리합니다.

은 참조 : AsyncTask and Looper.prepare() error

관련 문제