AlarmManager 定时任务详解

AlarmManager的使用

使用场景

  • 应用保活
  • 设置闹铃
  • 发送心跳包

功能说明:设置一个在未来的某个时间运行应用的PendingIntent 或者OnAlarmListener ,即使设备已经进入睡眠已设置的闹铃也会被保持,只有当设备关闭或是重启的时候会被清除

AlarmManager 对象获取

//AlarmManager 系统服务的获取方式
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

AlarmManager 提供的api介绍

1. 统一参数说明

AlarmType类型:
时间参照物,是否在休眠时候唤起

AlarmType 时间参照物 是否在休眠时候唤起设备
public static final int RTC_WAKEUP = 0 System.currentTimeMillis() ,当前系统的时间,单位ms
public static final int RTC = 1 System.currentTimeMillis(),当前系统的时间,单位ms
public static final int ELAPSED_REALTIME_WAKEUP = 2 SystemClock.elapsedRealtime() ,从系统启动到目前的时间(包括系统休眠),单位ms
public static final int ELAPSED_REALTIME = 3 SystemClock.elapsedRealtime(),从系统启动到目前的时间(包括系统休眠),单位ms

tips:
System.currentTimeMillis()的时间和实际时间可能不等,这个时间可以在设置中修改
常说的Unix 时间戳=System.currentTimeMillis()/1000 单位秒

定时任务触发类型
PendingIntent ,OnAlarmListener

任务触发类型 说明
PendingIntent 挂起的意图
OnAlarmListener 直接回调接口的 public void onAlarm() 方法

2. 功能方法

  • 设置定时任务相关方法
设置单次的定时任务 参数说明
set(@AlarmType int type, long triggerAtMillis, PendingIntent operation) triggerAtMillis:触发执行的时间;operation:挂起待执行的意图
set(@AlarmType int type, long triggerAtMillis, String tag, OnAlarmListener listener,Handler targetHandler) listener:待执行的回调;targetHandler:回调执行
设置单次准确的定时任务
public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation)
public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) 同上,type=RTC_WAKEUP
public void setExact(@AlarmType int type, long triggerAtMillis, String tag, OnAlarmListener listener, Handler targetHandler)
设置循环的定时任务
public void setRepeating(@AlarmType int type, long triggerAtMillis,long intervalMillis, PendingIntent operation) 这个循环定时,时间是精确地
public void setInexactRepeating(@AlarmType int type, long triggerAtMillis,long intervalMillis, PendingIntent operation) 与上面相反,是不精确的
设置在低功耗条件下也执行的定时任务
public void setAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,PendingIntent operation) 这个单次定时,时间是精确地
public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,PendingIntent operation) 与上面相反,是不精确的
设置在时间段执行的定时任务
public void setWindow(@AlarmType int type, long windowStartMillis, long windowLengthMillis,PendingIntent operation) 时间段左边界,时间段右边界
public void setWindow(@AlarmType int type, long windowStartMillis, long windowLengthMillis,String tag, OnAlarmListener listener, Handler targetHandler) 同上
  • 取消定时任务相关方法
方法 说明
public void cancel(PendingIntent operation) 根据PendingIntent 取消定时任务
public void cancel(OnAlarmListener listener) 根据OnAlarmListener 取消定时任务
  • 其他方法(设置系统时间、时区,获取下一次定时任务的信息)
方法 说明
public void setTime(long millis) 设置系统时间,需要权限android.permission.SET_TIME
public void setTimeZone(String timeZone) 设置系统时区,对所有apps生效;TimeZone.setDefault设置时区,只在当前app生效
public AlarmClockInfo getNextAlarmClock() 获取下一次定时任务信息,没有就为null

tips:
setTimeZone(String timeZone)的参数timeZone,在sdk>=Build.VERSION_CODES.M(23),TimeZone#getAvailableIDs()中字符串会抛出IllegalArgumentException

android不同版本对AlarmManager的影响

版本节点 影响 原因 解决办法
SDK < 19 使用 set() 或 setRepeating() 创建的闹铃是精确的 如果您已将 targetSdkVersion 设置为“18”或更低版本,那么在 Android 4.4 上运行时,您的闹铃的行为方式和在以前版本上一样
19= 使用 set() 或 setRepeating() 创建的闹铃将变得不准确 为提高电源效率,Android 现在批处理在合理的相似时间发生的所有应用的闹铃,以便系统仅唤醒设备一次,而不是多次唤醒设备来处理每个闹 无需精确建议使用新的 setWindow() 方法;任然需要精确的时钟时间(例如,日历事件提醒),那么您可以使用新的 setExact() 方法
23= 在低电耗模式下,您的应用会受到以下限制:系统忽略唤醒锁定;标准 AlarmManager 闹钟(包括 setExact() 和 setWindow())推迟到下一个维护期 针对低电耗模式和应用待机模式进行优化 如果您需要设置在设备处于低电耗模式时触发的闹钟,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。使用 setAlarmClock() 设置的闹钟将继续正常触发,系统会在这些闹钟触发之前不久退出低电耗模式

tips:
版本4.4(19)变更说明:https://developer.android.google.cn/about/versions/android-4.4
版本6.0(23)变更说明:https://developer.android.google.cn/about/versions/marshmallow/android-6.0-changes
6.0变更具体位置,低电耗模式和应用待机模式:https://developer.android.google.cn/training/monitoring-device-state/doze-standby

AlarmManager与Timer的区别

上下文依赖
AlarmManager android系统提供的系统服务功能,只有当系统关机或者重启任务才会失败不执行;能唤醒休眠锁,可在休眠时候执行
Timer 依赖于线程,线程又依赖于启动线程的app进程,也就是说程序杀死就终止;不能唤醒休眠锁,系统休眠会停止运行

AlarmManagerCompat版本兼容处理

implementation "com.android.support:support-compat:28.0.0"
//或者
implementation "androidx.core:core:1.3.0"

AlarmManagerCompat 代码:

public final class AlarmManagerCompat {
    public static void setAlarmClock(@NonNull AlarmManager alarmManager, long triggerTime, @NonNull PendingIntent showIntent, @NonNull PendingIntent operation) {
        if (VERSION.SDK_INT >= 21) {
            alarmManager.setAlarmClock(new AlarmClockInfo(triggerTime, showIntent), operation);
        } else {
            setExact(alarmManager, 0, triggerTime, operation);
        }

    }
    public static void setAndAllowWhileIdle(@NonNull AlarmManager alarmManager, int type, long triggerAtMillis, @NonNull PendingIntent operation) {
        if (VERSION.SDK_INT >= 23) {
            alarmManager.setAndAllowWhileIdle(type, triggerAtMillis, operation);
        } else {
            alarmManager.set(type, triggerAtMillis, operation);
        }

    }
    public static void setExact(@NonNull AlarmManager alarmManager, int type, long triggerAtMillis, @NonNull PendingIntent operation) {
        if (VERSION.SDK_INT >= 19) {
            alarmManager.setExact(type, triggerAtMillis, operation);
        } else {
            alarmManager.set(type, triggerAtMillis, operation);
        }

    }
    public static void setExactAndAllowWhileIdle(@NonNull AlarmManager alarmManager, int type, long triggerAtMillis, @NonNull PendingIntent operation) {
        if (VERSION.SDK_INT >= 23) {
            alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation);
        } else {
            setExact(alarmManager, type, triggerAtMillis, operation);
        }

    }
    private AlarmManagerCompat() {
    }
}

tips:
不多说AlarmManagerCompat 做了一些简单的版本兼容性处理

AlarmManager使用实例

  • 精准单次的定时任务
  • 精准循环的定时任务

AlarmManager,JobScheduler,WorkManager的功能

服务 功能介绍 版本问题
AlarmManager 提供在将来的某个时刻运行你的程序 API 19开始运行时间传递不精准
JobScheduler 提供特定时间并满足某些条件后运行你的程序 API 21开始使用,
WorkManager 是以上两个的进一步封装,Jetpack中的组件 WorkManager requires compileSdk version 28 or higher

此文要是对你有帮助,如果方便麻烦点个赞,谢谢!!!

你可能感兴趣的:(#,系统服务)