AlarmManager实例之后台音乐定时关闭

定时任务

常用的定时任务有Timer, Handler, AlarmManager

Timer

有一个明显的问题,就是它并不适合用于需要长期在后台运行的定时任务。

手机为了能让电池更加耐用,会采用自己的休眠策略而让CPU进入睡眠状态,极有可能导致Timer中的定时任务停止或者无法正常运行。

Handler

Handler的postDelay方法存在同样的问题,因为默认Handler依赖于线程,所以,只要进程被杀死,相关的定时操作也就无效了。

AlarmManager

它通过pendingIntent具有唤醒未启动进程的功能,即可以保证每次需要执行的定时任务的时候CPU都能正常工作。

注意当设备关机或者重启后,闹钟会被清除。

AlarmManager

实例——音乐定时关闭

初使化两个变量,方便在onDestroy时进行注销

private PendingIntent mPendingIntent;
private AlarmManager mAlarmManager;

实例化变量并设置定时任务

通过发送广播来执行定时事件

//注册广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.zqunyan.zgexplorer.musicplay.close");
registerReceiver(mBroadcabast, intentFilter);
mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_NO_CREATE);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//点击启动事件
mView.grpTimeClose.setOnCheckedChangeListener((radioGroup, i) -> {
    if(mPendingIntent != null) mAlarmManager.cancel(mPendingIntent);
    //if (mTimer != null) mTimer.cancel();
    int delay = 15000;
//            mTimer = new Timer();
//            mTimer.schedule(new TimerTask() {
//                @Override
//                public void run() {
//                    rTimer.cancel();
//                    MusicPlayActivity.this.finish();
//                    System.exit(0);
//                }
//            }, delay);
    //AlarmManager
    mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, mPendingIntent);
    }
});
private final BroadcastReceiver mBroadcabast = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        System.exit(0);
    }
};
@Override
protected void onDestroy() {
    if(mPendingIntent != null) mAlarmManager.cancel(mPendingIntent);
    //取消注册的广播
    unregisterReceiver(mBroadcabast);
    super.onDestroy();
}
常用方法

setAndAllowWhileIdle

如果想让闹钟在手机休眠时依然能够执行,则要使用 setAndAllowWhileIdle 和 setExactAndAllowWhileIdle 。

第一个参数为闹钟类型,一般为 AlarmManager.ELAPSED_REALTIME_WAKEUP 或者 AlarmManager.RTC_WAKEUP 。区别就是前者是从手机开机后的时间,包含了手机睡眠时间;而后者使用的就是手机系统设置中的时间

第二个参数表示任务首次执行时间:与第一个参数密切相关。第一个参数若为 AlarmManager.ELAPSED_REALTIME_WAKEUP ,那么当前时间就为 SystemClock.elapsedRealtime() ;若为 AlarmManager.RTC_WAKEUP ,那么当前时间就为 System.currentTimeMillis()

第三个参数表示对应的响应动作:一般都是去发送广播,然后在广播接收 onReceive(Context context, Intent intent) 中做相关操作

PendingIntent

Intent更加倾向于立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作,所以,可以把PendingIntent简单地理解为延迟执行的Intent.

FLAG

传入0表示不打算使用任何一种FLAG

  • FLAG_CANCEL_CURRENT

    如果要创建的PendingIntent已经存在了,那么在创建新的PendingIntent之前,原先已经存在的PendingIntent中的intent将不能使用

  • FLAG_NO_CREATE

    如果要创建的PendingIntent尚未存在,则不创建新的PendingIntent,直接返回null

  • FLAG_ONE_SHOT

    相同的PendingIntent只能使用一次,且遇到相同的PendingIntent时不会去更新PendingIntent中封装的Intent的extra部分的内容

  • FLAG_UPDATE_CURRENT

    如果要创建的PendingIntent已经存在了,那么在保留原先PendingIntent的同时,将原先PendingIntent封装的Intent中的extra部分替换为现在新创建的PendingIntent的intent中extra的内容

判断PendingIntent是否存在

public static boolean isPendingIntentAvailable(Context context) {
    Intent intent = new Intent();
    intent.setAction("com.zqunyan.zgexplorer.musicplay.close");
   	PendingIntent mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_NO_CREATE);
    return mPendingIntent != null;
}
if(mPendingIntent != null) mAlarmManager.cancel(mPendingIntent);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值