app耗电优化之四 使用AlarmManager对任务进行合理安排
AlarmManager 是用来设定定时任务。即用来设定那个任务在什么时候开始执行。为什么和省电有关系?这个需要和AlarmManager的使用先说起。
AlarmManager 实际上只起到一个定时发送意图的工具。当它在特定的时间里面发送一个意图出去,还需要一个接收器去处理这个任务。具体的实例如下:
1 获取AlarmManager对象
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
2 设定广播
final Intent intent = new Intent(Constants.ACTION_RETRY); intent.setClass(this, DownloadReceiver.class); /** * 设置闹钟唤起时机和要发送的Intent * 其中广播发送时机如下: * AlarmManager.RTC_WAKEUP (硬件闹钟,System.currentTimeMillis())在指定的时间内发送Intent,并且会唤醒设备。 * AlarmManager.RTC (硬件闹钟,System.currentTimeMillis())在指定的时间内发送广播,如果设备没有被唤醒则不会发送Intent,直到设备被唤醒才会发送Intent。 * AlarmManager.ELAPSED_REALTIME_WAKEUP (真是时间SystemClock.elapsedRealtime())在指定的时间内发送广播,并唤醒设备。 * AlarmManager.ELAPSED_REALTIME (真是时间SystemClock.elapsedRealtime())在指定的时间内发送广播,如果设备没有被唤醒则不会发送Intent,直到设备被唤醒才会发送Intent。 * now + nextActionMillis 参数表示广播发送时间 * SDK API < 19 * */ mAlarmManager.set(AlarmManager.RTC_WAKEUP, now + nextActionMillis, PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)); /** * 设置一个重复闹钟 * 其中interval值如下 * INTERVAL_FIFTEEN_MINUTES * INTERVAL_HALF_HOUR * INTERVAL_HOUR * INTERVAL_HALF_DAY * INTERVAL_DAY * SDK API < 19 高于19则不会被正常设定 */ mAlarmManager.setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation); /** * 设置一个重复闹钟,但是这个方法会比较省电,系统会将若干闹钟合并为一个执行,来减少唤醒次数。 * SDK API < 19 高于19则不会被正常设定 */ mAlarmManager.setInexactRepeating(int type, long triggerAtTime, long interval, PendingIntent operation); /** * SDK API >= 19 && SDK API < 23 在6.0上会在低电模式下无法使用。 */ mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), pendingIntent); /** * SDK API >=23 解决低电下不能正常启动闹钟 */ mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), pendingIntent); /** * 取消闹钟。 */ mAlarmManager.cancel(PendingIntent operation);
各个Android版本的设定方式个不一样,有些可能会失效,所以要多注意。
3 广播接受定义接受器
<receiver android:name=".DownloadReceiver" android:exported="false">
4 实现接收器
public class DownloadReceiver extends BroadcastReceiver{ public void onReceive(final Context context, final Intent intent){ //带有唤醒锁,从任务开始直到任务结束。 if (Constants.ACTION_RETRY.equals(action)) { startService(context); } } }
这里只是说了一个大概,具体怎么使用,具体情况下在细说。
下面细说怎么和省电产生了关系。
- 通过AlarmManager安排的任务,在任务执行的时候,会带一个唤醒锁。直到任务结束。
- AlarmManager.RTC_WAKEUP 和AlarmManager.ELAPSED_REALTIME_WAKEUP 这两种类型会唤醒设备开始执行任务。这两种基本上不会省电。
- AlarmManager.ELAPSED_REALTIME 和 AlarmManager.RTC 这两种之后在设备被唤醒时才发Intent执行任务。这两种是可以省电的
- 对于循环执行的任务,最好还是设定为 AlarmManager.ELAPSED_REALTIME 和 AlarmManager.RTC
至于AlarmManager.ELAPSED_REALTIME 和 AlarmManager.RTC 这两种的区别在于SystemClock.elapsedRealtime() 和 System.currentTimeMillis() 时间。前者手机不会被修改,而且不会因为休眠而停止。后者则会被修改。
付AlarmManager好Timer的区别。 其中AlarmManager 是基于独立硬件钟(RTC)模块定时。该硬件可以在CPU休眠时正常运行,所以他可以唤醒CPU。而Timer则使用会在CPU休眠时定时失效。
其他耗电优化方法请看 app耗电优化