注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/efficient-downloads/regular_updates.html
對于定期更新頻率的優化會基于設備的狀態,網絡連接,用戶行為和其喜好而有所變化。
我們在這一大系列課中,我們討論如何構建具有電池效率的應用,它們可以基于設備的狀態而調整刷新頻率。具體而言,包括了當你丟失了連接時,關閉后臺更新服務,以及當電量低時降低更新的頻次。
這節課將探討,在無線狀態機中,更新的頻率可以如何調整,以最小化后臺更新所造成的影響。
一). 使用谷歌云消息(Google Cloud Messaging)來代替輪詢?
每當你的應用輪詢服務來檢查是否有更新時,你就會啟動無線電設備,造成一些可能不必要的電量損失,對于一個標準3G網絡來說,至少需要消耗掉20秒的時間。
Google Cloud Messaging for Android (GCM) 是一種輕量化的機制,可以被用來從一個服務到一個特定應用實體進行數據的傳輸。使用GCM,你的服務可以通知一個運行在特定設備上的應用有一個新的數據可以獲取。
相較于輪詢,你的應用必須定期地ping服務器來查詢是否有新數據,而這一基于事件驅動的模型允許你的應用僅在它知道有數據要下載時才創建一個新的連接。
結果就是減少了不必要的連接,并在你的應用中減少了更新數據的時間。
GCM是使用TCP/IP長連接來實現的。它可以實現你自己的推送服務,使用GCM將是一個不錯的選擇。它能最小化長連接數目并允許平臺優化帶寬,最小化對電池壽命的影響。
二). 使用非精確重復提醒和指數退避來優化輪詢
在需要輪詢時,我們最好盡量將你應用的默認數據更新頻次設置的低,但卻不影響用戶的體驗。
一種簡單地方法是提供設置選項,讓用戶可以自行設置他們所需的更新頻率,允許他們自己在數據更新與電池壽命之間做出平衡。
當使用計劃更新時,使用非精確重復提醒可以允許系統在每一次提醒發生的時刻,做出一些時間上的推移。
int alarmType = AlarmManager.ELAPSED_REALTIME; long interval = AlarmManager.INTERVAL_HOUR; long start = System.currentTimeMillis() + interval; alarmManager.setInexactRepeating(alarmType, start, interval, pi);
如果一些提醒都被計劃于間隔某一小段時間后被激活,那么這一機制可以讓它們同時激活,允許每一個更新的完成僅依靠了一個單一的無線電狀態切換。
盡可能地將你的提醒類型設置為“
ELAPSED_REALTIME
”或者“
RTC
”而不是“
_WAKEUP
”。因為這可以使得提醒處于等待狀態,直到電話不再是待機模式后再被激活,從而進一步減少了對電池壽命的影響。
你還可以進一步減小這些計劃提醒的影響,方法是基于你的應用使用的頻次,減小計劃提醒的頻率。
一種方法是: 如果應用自上次更新后再也沒有被使用,那么 實現一個指數退避模式來減小更新的頻率(和/或你執行預取的頻率)。通常可以聲明一個最小的更新頻率,一旦應用被使用了就重置該更新頻率,例如:
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();
你也可以使用指數退避的方法來減少連接失敗和下載錯誤所造成的影響(譯者注:指數退避的思想在TCP/IP體系結構中,鏈路層的CSMA/CD協議里也有所體現)。
不管你是否能夠連接到你的服務器并下載數據, 初始化一個網絡連接的代價都是一樣的。對于是否傳輸成功很重要的時間敏感的傳輸,指數規避算法可以被用來減少重試的頻率來減少對電池壽命的影響,例如:
private void retryIn( long interval) { boolean success = attemptTransfer(); if (! success) { retryIn(interval *2 < MAX_RETRY_INTERVAL ? interval *2 : MAX_RETRY_INTERVAL); } }
相反的,對于可以容忍傳輸失敗的傳輸(如計劃更新),你可以簡單地忽略連接和傳輸嘗試。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
