定期更新的最佳频率将取决于设备的状态,网络连接,用户的行为和明确的用户喜好。
优化电池寿命,讨论了如何通过在基于主机设备的状态来修改其刷新频率,打造高效电池的应用程序。包括当你失去连接后禁用后台服务更新以及在电池电量低的时候减少更新的速度。
在这里会介绍更新频率是多少才会使得更新操作对无线电状态机的影响最小。
利用推送信息来替换电子邮件服务
每次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); } }