2012-10-12 44 views
0

在我之前的問題中:How to keep and access data in BroadcastReceiver?我已經得到了很好的答案,但是我在此着重於此。如何在Service和BroadcastReceiver之間發送和獲取數據?

有BroadcastReceiver,有服務。我想從接收器發送一些數據用於服務並返回數據。發起轉移的一方是接收方,而不是服務。

爲了簡單起見,我們假設接收方等待SCREEN_ON,然後詢問服務「這是用戶的生日」,服務器返回true或false。

如果我沒有弄錯,我應該將我的數據附加到服務的意圖,並調用startService,但如何獲取數據?

+0

要生硬,你的基本設計是有缺陷的恕我直言。服務而不是接收方應該是「發起轉讓的一方」。接收者僅僅是查找某個事件的一種手段,只不過是將事件的處理委託給服務進行處理。 – CommonsWare

+0

@CommonsWare,怎麼樣? Receiver接收到事件(如SCREEN_ON),因此它是唯一可以繼續進行的事件。 – greenoldman

+0

「因此它是唯一可以進一步進行的人」 - 並且通過將該事件的處理委派給處理服務來「進一步進行」。 – CommonsWare

回答

5

你不能這樣描述你的方式。 @CommonsWare正確,你選擇的架構有缺陷

BroadcastReceiver s是短命的。因此他們不能進行任何異步調用,他們不能執行任何需要「大量時間」的任務。您的BroadcastReceiver被某個事件觸發,如果您因該事件需要執行大量工作,則需要將該工作委託給Service

通常情況下(例如:內Activity),如果你想從一個Service請求信息,你可以綁定至Service並進行同步調用服務請求所需的數據,或者你可以撥打服務異步(即:發送一個Intent),然後監聽返回的結果(使用BroadcastReceiver)。由於BroadcastReceiver無法綁定到Service,因此這兩種方法都不適用於,因此無法進行異步調用。

編輯:從Android documentation複製有關資料以供參考這裏

接收機生命週期

BroadcastReceiver目的是僅適用於呼叫 到onReceive(Context, Intent)的持續時間。一旦你的代碼從這個 函數返回,系統就認爲該對象已經完成,不再是 活動。

這有可能,你可以在 onReceive(Context, Intent)實施做了哪些重要的影響:任何需要 異步操作不可用,因爲你需要從處理異步操作的功能 回報,但在 點BroadcastReceiver不再處於活動狀態,因此在異步操作 完成之前,系統可以自由地終止其進程。

特別是,您可能不會在BroadcastReceiver內顯示對話框或綁定到來自 的服務。對於前者,您應該改用API。對於後者,您可以使用 Context.startService()向服務發送命令。

+0

如果連接到服務是一個壞主意,那麼爲什麼Android手冊明確描述瞭如何連接到它 - 「你可以使用Context.startService( )發送命令到服務「? 「如果你需要做大量的工作」 - 我沒有對此說過一句話。 – greenoldman

+1

本文檔中的引用是正確的。它建議你做的是使用'BroadcastReceiver'來捕獲事件,然後調用'startService()'向'Service'發送一個命令,然後執行這個工作。使用'startService()'與**綁定到服務**不同。 'BroadcastReceiver'只是用來捕獲事件觸發器並將信息轉發給'Service'。我從Android文檔中複製了一些相關信息到我的答案中。 –

+0

那麼這是更「火與忘記」的方法呢?嘖嘖,這真的很糟糕,因爲它給我留下了唯一的選擇 - 保持靜態成員在服務中,並直接從接收器使用它(無需複製手冊,我引用它,所以我知道它在哪裏)。 – greenoldman

0

使用會話! 保存會話中的數據:

@Override 
    public void onReceive(Context context, Intent intent) 
    { 
     SessionManager session = new SessionManager(context); 
     // get user data from session 
     HashMap<String, Object> user = session.getUserDetails(); 

    // name 
    m_userId = (int)user.get(SessionManager.KEY_ID); 


    m_context = context; 

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 

    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ""); 

    wl.acquire(); 

    // Put here YOUR code. 
    //Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example 



    wl.release(); 
} 
相關問題