首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android AlarmManager 多任務調度最佳模式:單列表輪詢法

     編輯:程式設計綜合問答

核心思想

不同時註冊多個鬧鐘,而是維護一個按時間排序的任務列表,只為最近的一個任務設置鬧鐘;觸發後執行並移除,再為下一個任務設置。

數據結構

class AlarmTask implements Comparable<AlarmTask> {
    long triggerTime;   // 毫秒時間戳
    String id;          // 業務唯一標識
    Intent intent;      // 執行動作
    // getters/setters
    @Override public int compareTo(AlarmTask o) {
        return Long.compare(this.triggerTime, o.triggerTime);
    }
}

// 全局有序集合(線程安全)
ConcurrentSkipListSet<AlarmTask> taskQueue = new ConcurrentSkipListSet<>();

核心流程

  1. 添加任務:插入 taskQueue,若新任務成為首個 → setExact() 設置鬧鐘。
  2. 刪除任務:從 taskQueue 移除,若被刪除的是首個 → 取消舊鬧鐘,為新首個設置。
  3. 修改任務:刪除舊 + 添加新(或直接更新對象並重排)。
  4. 鬧鐘接收器:
    public class AlarmReceiver extends BroadcastReceiver {
        @Override public void onReceive(Context ctx, Intent intent) {
            AlarmTask task = taskQueue.pollFirst(); // 取出並移除首個
            if (task != null) {
                ctx.startService(task.intent); // 或 sendBroadcast
                scheduleNext(ctx); // 為新首個設置鬧鐘
            }
        }
        private void scheduleNext(Context ctx) {
            AlarmTask next = taskQueue.peekFirst();
            if (next != null) {
                AlarmManager am = (AlarmManager) ctx.getSystemService(ALARM_SERVICE);
                am.setExact(AlarmManager.RTC_WAKEUP, next.triggerTime, 
                    PendingIntent.getBroadcast(ctx, 0, new Intent(ctx, AlarmReceiver.class), FLAG_IMMUTABLE));
            }
        }
    }
    

UI 交互映射

  • 列表項 id ↔ AlarmTask.id,刪除/修改按鈕直接操作 taskQueue。
  • 頁面刷新時遍歷 taskQueue 顯示剩餘任務。

優勢總結

傳統多鬧鐘單列表輪詢
系統鬧鐘數 = 任務數,受限 500+ 上限始終只有 1 個系統鬧鐘,無上限壓力
增刪改需逐個 PendingIntent 操作只操作隊首,邏輯極簡
重啟後需遍歷恢復所有啟動時讀取持久化隊列,僅恢復隊首

Android 官方文檔明確建議:「盡量減少鬧鐘數量」。單列表輪詢法完美契合,且代碼量最少、邏輯最清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved