2010-02-18 64 views
4

我有一個帶有兩個線程(主線程和數據加載程序)的應用程序。當數據加載器完成後,它將一個Runnable對象發佈到主線程(如DevGuide中所述),但它永遠不會交付和運行。處理程序未能向主線程傳遞消息或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永遠不會運行()。 我也嘗試發送簡單的消息,而不是發佈runnable(例如,m_handler.sendEmptyMessage(1)) - 它們從未在主線程中傳遞到處理程序的回調函數。

我在這裏錯過了什麼?

感謝提前:)

回答

1

A Handler需要Looper才能工作。 Looper提供了Handler所需的消息隊列。

Activity的所有實例都具有Looper,因爲其中一個用於處理UI事件,但您可以在別處創建Looper的實例。

看看你的日誌輸出,看看Android是否抱怨沒有Looper

如果是,你也許可以修復由以下內容添加到您的onCreate()方法的頂部:

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

而從後面的代碼去除m_handler初始化。

+0

我認爲是這樣,但Looper確實創建。因爲當我嘗試自己創建它(包括嘗試上面的建議)時,我得到: 「java.lang.RuntimeException:每個線程只能創建一個Looper」 另外我剛剛發現代碼(不變)很好,當在一個完整的應用程序在操作系統內運行。另一方面,當我將它作爲測試用例運行時,它無法工作... 任何提示? Looper是好的,它不是空的,沒有例外,日誌中沒有錯誤。我很困惑。 – dimsuz 2010-02-18 16:46:12

+0

感謝您的提示!我的代碼不在一個活動內,因此不在循環內... 我想知道爲什麼通過處理程序發送的消息只在調用線程停止時纔會發送。 – Sney 2011-06-22 06:08:16

0

Handler只能在一個Activity AFAIK。您正試圖在Application中使用它。

+0

我剛剛發現,作爲一個測試運行時,當作爲OS的應用程序中運行這個非常的代碼工作,但失敗......所以我想這是別的東西丟失。也許與活動有關...... – dimsuz 2010-02-18 16:40:54

0

撥打Looper.prepare()的另一種方法是致電new Handler(Looper.getMainLooper())。調用Looper.prepare()時遇到的問題是,當線程中已經存在循環時,它會拋出異常。有可能你正在編寫必須在不同環境下運行的代碼,並且此解決方案將處理更多的案例。

參見: AsyncTask and Looper.prepare() error