2013-03-16 94 views
6

我正在構建一個應用程序,它將定期監視電池狀態,wifi連接和位置數據,並將結果寫入文件(並稍後將它們發送到服務器)。應該禁用安裝應用程序監視 - 但啓用它的用戶應該在重新啓動後繼續。大量的閱讀後,我已經意識到我已經基本2個選擇:Android設計:背景長時間運行服務或AlarmManager?

  • 子類Service和我的活動火它關閉。將它設置在前景,STICKY和什麼不是,並希望它不會被android殺死 - 並注意如果android重新創建它(實際上應該有3個服務,因此它們之間的同步可能會混亂)。在服務中啓動一個線程(無需執行程序,我猜),並有Thread.sleep(REGULAR_INTERVAL)。喚醒,收集數據寫入文件。廣播收集到的信息並將其顯示在我的活動中(如果它恰好在運行)(它將註冊一個廣播接收器)。沖洗並重復while(true)。有辦法打斷這個
  • 我的活動有註冊一個PendingIntent與AlarmManager - 這將運行每個REGULAR_INTERVAL。我還沒有深入研究過這種方法的技術細節 - 但我希望我能夠讓這個PendingIntent創建並運行一個IntentService(這似乎是一條可行的路線 - 讓Thread機制免費以及關閉在其自己的)。這種方法的一些骨架代碼將受到歡迎。

我想我必須註冊在這兩種情況下啓動接收器檢查共享偏好(已經做到了這一點),並在情況1啓動服務(S),而在情況2寄存器的報警事件的接收器並設置警報管理器 - 這是我需要一些骨架代碼的部分。

所以 - 在我開始構建之前 - 這將是首選方法?

在回顧 - 應用程序應該監視一些手機屬性,並將它們寫入文件,直到用戶選擇關閉它。

+0

你的用戶或許會殺了你,如果你保持一個'Service'活着連續排水他們的手機電池只是聚集在一定的時間間隔圓頂數據。如果需要,可以使用第二種方法,帶有帶額外WakeLocks的'IntentService'(查看CommonsWare的'WakefullIntentService')。 – Luksprog 2013-03-16 16:06:12

+0

@Luksprog:謝謝 - 我需要鎖嗎?在接收報警的廣播接收機中(仍在研究如何實現)? – 2013-03-16 16:10:44

+0

爲什麼是反面投票? – 2013-03-16 21:11:18

回答

6

,而在情況2註冊的報警事件的接收器,並設置報警經理了

您的接收器將已經通過清單進行登記。

這將是首選方法?

AlarmManager,假設REGULAR_INTERVAL通常很長(例如幾分鐘)。理想情況下,該間隔是用戶可配置的。

如果你打算這樣做,即使該設備是睡着了,你的選擇#1根本不會工作,除非你始終保持WakeLock,這將導致你的用戶想拍攝你的臉用霰彈槍。

這種方法的一些骨架代碼將受到歡迎。

Here is a sample app演示使用的AlarmManager用於非_WAKEUP報警(即,您只需要這些事件,而該設備已經醒了因其他原因發生)。

Here is a sample app演示使用AlarmManager_WAKEUP報警,使用my WakefulIntentServiceWakefulIntentService(或類似的東西)是必要的,因爲AlarmManager不會讓設備保持非常長的時間(只需要足夠長的時間,以達到BroadcastReceiveronReceive()),所以您需要採取額外措施來保持設備足夠長的時間以待您工作。 理論上,你的工作可能足夠快,只需要在的BroadcastReceiver,避免需要混亂WakefulIntentService。但是,您將每次執行磁盤I/O,理想情況下不應在主應用程序線程上執行,其中onReceive()被調用。而且,當你去上傳你的數據時,你可能需要一個WakefulIntentService然後,無論如何,如果你想在後臺做這件事。

+0

謝謝 - 爲什麼註冊BroadcastReceiver在清單(而不是啓動一個 - 這必須在那裏)?這是否意味着它會一直被註冊 - 導致一些開銷? BootReceiver - >'是否啓用了監視? (爲報警註冊一個接收器;設置報警):返回似乎更經濟。此外,AlarmReceiver將運行在我的主UI線程中?當我的活動(只顯示收集的數據並允許啓用/禁用監控)正常時,情況就會如此 - 不是嗎?否則就不會有UI線程(或者它不會有所作爲) - 我錯了嗎? – 2013-03-16 16:25:59

+0

@Mr_and_Mrs_D:「爲什麼要在清單中註冊BroadcastReceiver」 - 否則,您需要隨時保留一個組件(例如Service),這是切換到「AlarmManager」後的一個要點。你不* *想要一直佔用記憶。 「這是不是意味着它會一直註冊 - 導致一些開銷?」 - 它只會被你的'AlarmManager'使用。 「另外AlarmReceiver將在我的主UI線程中運行?」 - 在主應用程序線程上調用'BroadcastReceiver'的'onReceive()'。 – CommonsWare 2013-03-16 16:28:09

+0

@Mr_and_Mrs_D:「否則不會有UI線程」 - 總是有一個「UI線程」,更準確地稱爲「主應用程序線程」。如果您在主應用程序線程上花費了太多時間,即使使用'onReceive()',Android也會終止您的操作。 – CommonsWare 2013-03-16 16:29:11

0

根據循環任務的長度,您可以選擇幾種方法之一。這個問題討論他們 - Scheduling recurring task in Android

當任務睡眠時間是15分鐘或更長的時間使用AlarmManager很方便。該模式是衆所周知的。

+0

@CommonsWare:我有類似的情況來執行一些任務(GPS定位),間隔1分鐘。我在我的主要活動中使用Handler,它將如何影響我的應用程序 – Tushar 2013-06-01 19:20:44