阅读:http://blog.csdn.net/kesenhoo/article/details/7390519
http://developer.android.com/training/efficient-downloads/efficient-network-access.html
Optimizing Downloads for Efficient Network Access 基于有效的网络访问优化下载
Minimizing the Effect of Regular Updates 最小化定期轮训更新的影响
Redundant Downloads are Redundant 冗余的下载都是多余的
Modifying your Download Patterns Based on the Connectivity Type 基于连接类型修改下载模式
一。基于有效的网络访问优化下载
原理:
一次网络访问差不多消耗20s的高电量
操作:
1.批量传输与连接,如预取数据
2.减少连接次数
二。最小化定期轮训更新的影响
1.Google Cloud Messaging for Android (GCM)
谷歌推送服务 事件驱动 减少了网络连接次数,也优化了带宽,还减少了对电量的消耗。
2.Optimize Polling with Inexact Repeating Alarms and Exponential Backoffs
通过不定时的重复提醒与指数退避来优化轮询操作
不定时提醒闹钟
如果需要使用轮询机制,在不影响用户体验的前提下,当然设置默认更新频率是越低越好[减少电量的浪费]。一个简单的方法是给用户提供更新频率的选择,允许用户自己来处理如何平衡数据及时性与电量的消耗。当设置安排好更新操作后,可以使用不确定重复提醒的方式来允许系统把当前这个操作进行定向移动(比如推迟一会)
int alarmType = AlarmManager.ELAPSED_REALTIME; long interval = AlarmManager.INTERVAL_HOUR; long start = System.currentTimeMillis() + interval; alarmManager.setInexactRepeating(alarmType, start, interval, pi);
指数退避算法: 间隔时间未发生 则间隔时间加倍
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();
private void retryIn(long interval) { boolean success = attemptTransfer(); if (!success) { retryIn(interval*2 < MAX_RETRY_INTERVAL ? interval*2 : MAX_RETRY_INTERVAL); } }
三。冗余的下载都是多余的 使用缓存避免重复下载
1.本地缓存文件
long currentTime = System.currentTimeMillis()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); long expires = conn.getHeaderFieldDate("Expires", currentTime); long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime); setDataExpirationDate(expires); if (lastModified < lastUpdateTime) { // Skip update } else { // Parse update }
2.Use the HttpURLConnection Response Cache 使用HttpUrlConnection catch
private void enableHttpResponseCache() { try { long httpCacheSize = 10 * 1024 * 1024; // 10 MiB File httpCacheDir = new File(getCacheDir(), "http"); Class.forName("android.net.http.HttpResponseCache") .getMethod("install", File.class, long.class) .invoke(null, httpCacheDir, httpCacheSize); } catch (Exception httpResponseCacheNotAvailable) { Log.d(TAG, "HTTP response cache is unavailable."); } }
四。基于连接类型修改下载模式
1.Use Wi-Fi [使用Wi-Fi]
在大多数情况下,Wi-Fi电波会在使用相对较低的电量的情况下提供一个相对较宽的带宽。因此,我们需要努力争取尽量使用Wi-Fi来传递数据。
我们可以使用Broadcast Receiver来监听当网络连接切换为Wi-Fi,这个时候我们可以进行大量的数据传递操作,例如下载,执行定时的更新操作,甚至是在这个时候加大更新的频率。这些内容都可以在前面的课程中找到。
2.使用更大的带宽来下载更多的数据,而不是经常去下载
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); int PrefetchCacheSize = DEFAULT_PREFETCH_CACHE; switch (activeNetwork.getType()) { case (ConnectivityManager.TYPE_WIFI): PrefetchCacheSize = MAX_PREFETCH_CACHE; break; case (ConnectivityManager.TYPE_MOBILE): { switch (tm.getNetworkType()) { case (TelephonyManager.NETWORK_TYPE_LTE | TelephonyManager.NETWORK_TYPE_HSPAP): PrefetchCacheSize *= 4; break; case (TelephonyManager.NETWORK_TYPE_EDGE | TelephonyManager.NETWORK_TYPE_GPRS): PrefetchCacheSize /= 2; break; default: break; } break; } default: break; }