2011-08-29 31 views
3

我有我的主UI,我有一個AsyncTask運行。我想與AsyncTask溝通,讓它在非UI線程上運行一些東西。所以我想這樣做是:與AsyncTask線程通信?處理程序不工作?

protected class WifiMon extends AsyncTask<Context, Integer, String> 
{ 
    Context parent; 
    CoexiSyst coexisyst; 
    private static final String WIMON_TAG = "WiFiMonitor"; 
    private int PCAP_HDR_SIZE = 16; 
    private int _scan_pkts_left; 

    public Handler _handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 

      // We invoke a scan, and then read in all of the packets 
      // captured from the scan. 
      if(msg.obj == ThreadMessages.WIFI_SCAN_START) { 
       Log.d(TAG, "Got message to start Wifi scan"); 
       int start_rxpkts = getRxPacketCount(); 
       runCommand("/data/data/com.gnychis.coexisyst/files/iw dev wlan0 scan"); 
       _scan_pkts_left = getRxPacketCount() - start_rxpkts; 
       Log.d(TAG, "Finished Wifi scan"); 
      } 
     } 
    }; 
    ... 
} 

然而,似乎當傳入消息來如,的handleMessage()實際上是在UI線程中運行。我知道這是因爲runCommand()阻塞了5秒,而我的UI最終在5秒內沒有響應。

爲什麼的handleMessage()非UI線程上沒有運行?線程之間是否還有其他一些首選的通信方式?

+0

忘記AyncTask並用針來代替。 )https://github.com/ZsoltSafrany/needle –

回答

2

doInBackground()方法創建的處理程序對象。
或者
你可以把處理程序在一個單獨的線程,如果它是獨立的Aysnctask的。

編輯:

mHandlerThread = new HandlerThread("some_name"); 
mHandlerThread.start(); 

/* we need to wait to get the looper instance */ 
while(!mHandlerThread.isAlive()) {}; 
mHandler = new Handler(mHandlerThread.getLooper(), null); 
+0

把它在doInBackground()調用該異常:08-29 00:07:09.321:ERROR/AndroidRuntime(8084):了java.lang.RuntimeException:致能在線程裏面沒有調用Looper.prepare() – gnychis

+0

然後你應該把它放在一個單獨的線程中。創建一個'HandlerThread',然後將其循環傳遞給處理程序。 – Ronnie

+0

我編輯了我的答案。 – Ronnie

0

以下方法工作在UI線程

onProgressUpdate 

,或者你可以創建一個接口,並註冊事件

0

它運行在UI線程,因爲,處理程序始終在創建它的線程上執行。在這種情況下,它將是UI線程。

我認爲,你如果你不真正需要的處理程序。相反,只需在WifiMon任務中擁有一些標誌或適當的數據結構。現在你可以在任何地方設置這個標誌和所需的參數(當然有適當的警衛)。如果你想讓它在與任務本身相同的線程中執行,那麼無論如何你都必須在中斷doInBackground主邏輯,並且此時只需檢查你的標誌。

如果你想另一個線程,只是引進來啓動它的方法。比如:

protected class WifiMon extends AsyncTask<Context, Integer, String> 
{ 
    public void startScan() { 
     Thread t = new Thread() { 
     public void run() { 
      // Scan here and read/update properties of WifiMon 
     } 
     }; 
     t.start(); 
    } 
} 

,而是

wifimon._handler.post(...); 

使用

wifimon.startScan();