You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用startActivity(Intent)时每次都会销毁Activity,原因是什么?

嘿,我来帮你捋捋这个Activity中重复Alarm设置的问题~

关于重复Alarm设置的分析与建议

首先你提到的onDestroy()调用时机确实很关键——系统只有在内存极度紧张的时候才会触发它,所以绝对不能依赖这个方法去取消Alarm,这一点你抓得非常准。

结合你给出的startEMAAlarm()代码片段,我整理几个核心注意点:

  • 触发时间的边界处理:你代码里把Calendar设为每天8:30,但如果当前时间已经过了这个点,第一次Alarm会直接推迟到第二天。如果想让当天没过8:30就触发当天的,过了就触发第二天的,得加个判断逻辑:

    if (cal.getTimeInMillis() < System.currentTimeMillis()) {
        cal.add(Calendar.DAY_OF_MONTH, 1); // 已过触发时间,顺延至次日
    }
    
  • 避免重复创建Alarm:onCreate()可能会被多次调用(比如屏幕旋转、Activity重建),如果每次都重新设置,会导致多个重复的Alarm同时运行。建议设置前先取消同类型的旧Alarm:

    // 用固定的requestCode创建PendingIntent,确保能匹配到旧的实例
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    // 设置前先取消旧Alarm
    alarmMgr.cancel(pendingIntent);
    // 再设置新的Alarm
    
  • 适配不同Android版本的Alarm精度:从API 19开始,setRepeating()会变成非精准触发(系统为省电调整时间)。如果需要精准的每日提醒,建议用setExactAndAllowWhileIdle()配合广播接收器,每次触发后再重新设置下一次Alarm:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmMgr.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
    } else {
        alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 
            AlarmManager.INTERVAL_DAY, pendingIntent);
    }
    
  • 不要依赖onDestroy()取消Alarm:既然系统不一定会调用它,那如果需要在用户退出App时停止Alarm,可以在用户主动点击退出按钮的逻辑里主动取消,或者用Service/WorkManager来统一管理Alarm的生命周期。

最后给你补全startEMAAlarm()的完整示例:

public void startEMAAlarm(){ 
    Log.d(TAG, "startEMAAlarm: in start ema alarm"); 
    Calendar cal = Calendar.getInstance(); 
    // 设定每日8:30触发
    cal.set(Calendar.HOUR_OF_DAY, 8); 
    cal.set(Calendar.MINUTE, 30);
    cal.set(Calendar.SECOND, 0);
    
    // 处理当前时间已过触发点的情况
    if (cal.getTimeInMillis() < System.currentTimeMillis()) {
        cal.add(Calendar.DAY_OF_MONTH, 1);
    }
    
    AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, YourAlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    
    // 先取消旧Alarm,避免重复
    alarmMgr.cancel(pendingIntent);
    
    // 根据系统版本选择合适的Alarm设置方式
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmMgr.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
    } else {
        alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 
            AlarmManager.INTERVAL_DAY, pendingIntent);
    }
}

另外要注意,Android 8.0+对后台广播有限制,你的YourAlarmReceiver如果是静态注册在Manifest里,可能无法正常接收广播,建议改用动态注册或者通过PendingIntent启动前台服务来处理通知逻辑。

内容的提问来源于stack exchange,提问作者gwicks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:11:22