定期更新的最佳頻率將取決於裝置的狀態,網路連接,使用者的行為和明確的使用者喜好。
最佳化電池壽命,討論了如何通過在基於主機裝置的狀態來修改其重新整理頻率,打造高效電池的應用程式。包括當你失去串連後禁用後台服務更新以及在電池電量低的時候減少更新的速度。
在這裡會介紹更新頻率是多少才會使得更新操作對無線電狀態機器的影響最小。
利用推送資訊來替換電子郵件服務
每次app去向server詢問檢查是否有更新操作的時候會啟用無線電,這樣造成了不必要的能量消耗(在3G情況下,會差不多消耗20秒的能量)。
C2DM是一個用來從server到特定app傳輸資料的輕量級的機制。使用C2DM,server會在某個app有新資料的時候通知app有這個訊息。比起輪詢方式(app為了即時拿到最新的資料需要定時向server請求資料),C2DM這種有事件驅動的模式會在僅僅有資料更新的時候通知app去建立網路連接來擷取資料。
其結果是減少不必要的串連,並減少更新的資料的延遲,在您的應用程式中。
C2DM需要通過使用固定TCP/IP來實現操作。當你可以聲明推送服務時,最好使用C2DM。很明顯,使用C2DM既減少了網路連接次數,也最佳化了頻寬,還減少了對電量的消耗。“
通過不定時的重複提醒與指數退避來最佳化輪詢操作
如果需要使用輪詢機制,在不影響使用者體驗的前提下,當然設定預設更新頻率是越低越好[減少電量的浪費]。 一個簡單的方法是給使用者提供更新頻率的選擇,允許使用者自己來處理如何平衡資料及時性與電量的消耗。當設定安排好更新操作後,可以使用不確定重複提醒的方式來允許系統把當前這個操作進行定向移動。
int alarmType = AlarmManager.ELAPSED_REALTIME; long interval = AlarmManager.INTERVAL_HOUR; long start = System.currentTimeMillis() + interval; alarmManager.setInexactRepeating(alarmType, start, interval, pi);
若是多個提醒都被做了“定向移動”,那麼很有可能到某個點同時被觸發,那麼這樣就可以使得多個操作在同一個無線電狀態下操作完。
如果可以,請設定提醒的類型為ELAPSED_REALTIME or RTC而不是_WAKEUP。這樣能夠更進一步的減少在等待同時被觸發的時候對電量的消耗。
我們還可以通過根據app被使用的頻率來有選擇性的減少更新的頻率
另一個方法在app在上一次更新操作之後還未被使用的情況下,使用指數退避演算法(exponential back-off algorithm)來減少更新頻率。當然我們也可以使用一些類似指數退避的方法:
SharedPreferences sp = context.getSharedPreferences(PREFS, Context.MODE_WORLD_READABLE); boolean appUsed = sp.getBoolean(PREFS_APPUSED, false); long updateInterval = sp.getLong(PREFS_INTERVAL, DEFAULT_REFRESH_INTERVAL); if (appUsed) if ((updateInterval * = 2) > MAX_REFRESH_INTERVAL) updateInterval = MAX_REFRESH_INTERVAL; Editor spEdit = sp.edit(); spEdit.putBoolean(PREFS_APPUSED, false); spEdit.putLong(PREFS_INTERVAL, updateInterval); spEdit.apply(); rescheduleUpdates(updateInterval); executeUpdateOrPrefetch();
你可以使用類似的指數退避演算法來減少失敗串連和下載錯誤的影響
初始化一個網路連接的花費不會因為是否成功下載了資料而改變。我們可以使用指數退避演算法來減少重複嘗試(retry)的次數,這樣能夠避免浪費電量。例如:
private void retryIn(long interval) { boolean success = attemptTransfer(); if (success) { retryIn(interval* 2 < MAX_RETRY_INTERVAL ? interval* 2 : MAX_RETRY_INTERVAL); } }另外,對於轉移有失敗(如定期更新),您可以簡單地忽略串連失敗和轉移的嘗試。