2013-04-11 31 views
1

我有一些關於Android的BroadcastReceiver的設計問題。Android BroadcastReceiver:線程模型和非重疊

我的情況如下:連接某個WiFi網絡時,檢測是否有強制門戶,如果有,則對其進行身份驗證。該場景涉及網絡I/O並需要幾秒鐘才能完成(尤其是當您需要使用密碼等待SMS時)。

通過調試BroadcastReceiver Wifi狀態更改,我發現它在應用程序的主線程上調用。這是幾分鐘後我不知道的事情。我是這樣說的,而不是問,因爲這個問題也是我發現的結果。

在無線驗證階段,我應該處理用戶突然斷開連接(例如由於熱點故障,用戶走出範圍......)並重新連接的情況,由避免兩個廣播重疊和可能取消認證最終失敗。

當我發現BroadcastReceiver在主線程中執行後,我得出結論,我需要一個AsyncTask來執行網絡I/O,但隨意提出其他想法。

問題是:如果連續廣播在長時間運行的任務中間被觸發,我該如何阻止?事實上,AsyncTask可以被取消,但是我怎樣才能存儲一個AsyncTask的共享實例,以便從另一個BroadcastReceiver中取消它,而不會使我的生活過於複雜?

Android是否BroadcastReceiver s 事實上的單身人士還是Android會在每次需要播放新廣播時創建一個新的已聲明接收器實例嗎?

回答

1

我來,我需要一個的AsyncTask來執行網絡I/O

可能不是結論。

但隨時提出其他想法

當別人指出的,一個IntentService是一個更好的主意。

問題的一部分是,你已經告訴我們幾乎沒有具體的關於你的接收器。特別是,您沒有說明您是如何註冊有問題的接收者:清單或registerReceiver()?理想的問題建議會考慮到這一點。 IntentService答案和這一個,假設你正在通過清單註冊。

爲Android BroadcastReceivers事實上的單身或沒有Android的創建聲明接收器的每一個它需要觸發一個新的廣播時間一個新的實例?

如果要註冊清單中的接收器,爲每個廣播創建的BroadcastReceiver的新實例。更重要的是,Android沒有任何信號傳遞,在這種情況下,您的流程需要堅持一次onReceive()返回,這就是爲什麼AsyncTask不是一個好主意,IntentService更好。

如果連續廣播在長時間運行的任務中間被觸發,我該如何阻止?

也許你不會「停止這樣做」,因爲很可能你所做的事不能以任何有意義的意義被「停止」,也不會讓你的數據處於不確定狀態。

如果您確實確信自己需要「停止該操作」,則需要創建自己的Service,該工具具有IntentService的某些特徵(例如,它具有其後臺線程),但允許您操縱命令隊列,停止正在進行的工作等

,但我怎麼能存儲的AsyncTask的共享實例,以便從不同的BroadcastReceiver取消它沒有我的生活變得複雜太多了?

你不能,容易,除了可能作爲一個靜態數據成員。但是由於在任務完成之前Android很可能會擺脫您的流程,因此使用AsyncTask並不是一個好主意。

+0

我在清單 – 2013-04-11 20:23:48

+0

中註冊了我的接收器「可能您不會」停止該操作「,因爲您很可能無法以任何有意義的意義」停止「您的操作,而不會使您處於不確定狀態數據。」 - 幸運的是在我的情況下,我可以取消註冊SMS接收器(從代碼)並殺死線程,但是您的評論在一般情況下是正確的 – 2013-04-11 20:37:52

1

對於需要一些時間執行的任務啓動Service是一種很好的做法。

在你的情況下,我會使用IntentService。這個特定的Service在後臺線程中執行,它也處理內部隊列,所以如果你啓動它兩次,第二個任務將在第一個任務完成後執行。我強烈建議您使用IntentService而不是AsyncTask

1

BroadcastReceiverIntentService完美協作,它依次處理來自UI線程的傳入意圖。 Services guide有一個實現示例。您的BroadcastReceiver然後只需要調用IntentService。