import AsyncStorage from '@react-native-async-storage/async-storage'; import * as BackgroundFetch from 'expo-background-fetch'; import * as TaskManager from 'expo-task-manager'; // 任务类型定义 export interface BackgroundTask { id: string; name: string; handler: (data?: any) => Promise; options?: { minimumInterval?: number; // 最小间隔时间(分钟) stopOnTerminate?: boolean; // 应用终止时是否停止 startOnBoot?: boolean; // 设备重启时是否启动 }; } // 任务状态 export interface TaskStatus { id: string; isRegistered: boolean; lastExecution?: Date; nextExecution?: Date; executionCount: number; lastError?: string; } // 后台任务管理器类 class BackgroundTaskManager { private static instance: BackgroundTaskManager; private tasks: Map = new Map(); private taskStatuses: Map = new Map(); private isInitialized = false; // 单例模式 public static getInstance(): BackgroundTaskManager { if (!BackgroundTaskManager.instance) { BackgroundTaskManager.instance = new BackgroundTaskManager(); } return BackgroundTaskManager.instance; } // 初始化后台任务管理器 public async initialize(): Promise { if (this.isInitialized) { return; } try { this.isInitialized = true; // 注册后台任务 await this.registerBackgroundTask(); // 加载已保存的任务状态 await this.loadTaskStatuses(); console.log('后台任务管理器初始化成功'); } catch (error) { console.error('后台任务管理器初始化失败:', error); throw error; } } // 注册后台任务 private async registerBackgroundTask(): Promise { const BACKGROUND_FETCH_TASK = 'background-fetch-task'; console.log('注册后台获取任务'); // 定义后台获取任务 TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { console.log('后台获取任务被系统调用'); const now = new Date(); try { console.log(`开始执行后台任务 - ${now.toISOString()}`); // 执行所有注册的任务 const results = await this.executeAllTasks(); console.log('后台任务执行完成:', results); // 返回成功状态 return BackgroundFetch.BackgroundFetchResult.NewData; } catch (error) { console.error('后台任务执行失败:', error); return BackgroundFetch.BackgroundFetchResult.Failed; } }); // 注册后台获取任务 try { const status = await BackgroundFetch.getStatusAsync(); if (status === BackgroundFetch.BackgroundFetchStatus.Available) { await BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { minimumInterval: 15 * 60, // 15分钟(以秒为单位) stopOnTerminate: false, startOnBoot: true, }); console.log('后台获取任务注册成功'); } else { console.warn('后台获取不可用,状态:', status); } } catch (error) { console.error('注册后台获取任务失败:', error); } } // 注册自定义任务 public async registerTask(task: BackgroundTask): Promise { try { // 检查任务是否已存在 if (this.tasks.has(task.id)) { console.warn(`任务 ${task.id} 已存在,将被覆盖`); } // 保存任务 this.tasks.set(task.id, task); // 初始化任务状态 if (!this.taskStatuses.has(task.id)) { this.taskStatuses.set(task.id, { id: task.id, isRegistered: true, executionCount: 0, }); } // 保存任务状态 await this.saveTaskStatuses(); console.log(`任务 ${task.id} 注册成功`); } catch (error) { console.error(`注册任务 ${task.id} 失败:`, error); throw error; } } // 取消注册任务 public async unregisterTask(taskId: string): Promise { try { // 移除任务 this.tasks.delete(taskId); // 更新任务状态 const status = this.taskStatuses.get(taskId); if (status) { status.isRegistered = false; await this.saveTaskStatuses(); } console.log(`任务 ${taskId} 取消注册成功`); } catch (error) { console.error(`取消注册任务 ${taskId} 失败:`, error); throw error; } } // 手动执行任务 public async executeTask(taskId: string, data?: any): Promise { try { const task = this.tasks.get(taskId); if (!task) { throw new Error(`任务 ${taskId} 不存在`); } console.log(`开始执行任务: ${taskId}`); // 执行任务 await task.handler(data); // 更新任务状态 const status = this.taskStatuses.get(taskId); if (status) { status.lastExecution = new Date(); status.executionCount += 1; status.lastError = undefined; await this.saveTaskStatuses(); } console.log(`任务 ${taskId} 执行成功`); } catch (error) { console.error(`执行任务 ${taskId} 失败:`, error); // 更新错误状态 const status = this.taskStatuses.get(taskId); if (status) { status.lastError = error instanceof Error ? error.message : String(error); await this.saveTaskStatuses(); } throw error; } } // 执行所有任务 public async executeAllTasks(): Promise<{ [taskId: string]: 'success' | 'failed' }> { const results: { [taskId: string]: 'success' | 'failed' } = {}; for (const [taskId, task] of this.tasks) { try { await this.executeTask(taskId); results[taskId] = 'success'; } catch (error) { console.error(`执行任务 ${taskId} 失败:`, error); results[taskId] = 'failed'; } } return results; } // 获取任务状态 public getTaskStatus(taskId: string): TaskStatus | undefined { return this.taskStatuses.get(taskId); } // 获取所有任务状态 public getAllTaskStatuses(): TaskStatus[] { return Array.from(this.taskStatuses.values()); } // 获取已注册的任务列表 public getRegisteredTasks(): BackgroundTask[] { return Array.from(this.tasks.values()); } // 检查后台任务状态 public async getBackgroundTaskStatus(): Promise { return await BackgroundFetch.getStatusAsync(); } // 保存任务状态到本地存储 private async saveTaskStatuses(): Promise { try { const statuses = Array.from(this.taskStatuses.values()); await AsyncStorage.setItem('@background_task_statuses', JSON.stringify(statuses)); } catch (error) { console.error('保存任务状态失败:', error); } } // 从本地存储加载任务状态 private async loadTaskStatuses(): Promise { try { const statusesJson = await AsyncStorage.getItem('@background_task_statuses'); if (statusesJson) { const statuses: TaskStatus[] = JSON.parse(statusesJson); statuses.forEach(status => { this.taskStatuses.set(status.id, status); }); } } catch (error) { console.error('加载任务状态失败:', error); } } // 清理过期的任务状态 public async cleanupTaskStatuses(): Promise { const now = new Date(); const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); for (const [taskId, status] of this.taskStatuses) { if (status.lastExecution && status.lastExecution < thirtyDaysAgo && !status.isRegistered) { this.taskStatuses.delete(taskId); } } await this.saveTaskStatuses(); } // 调试函数:强制触发后台任务执行 public async debugExecuteBackgroundTask(): Promise { console.log('=== 调试:手动触发后台任务执行 ==='); try { // 获取后台任务状态 const status = await this.getBackgroundTaskStatus(); console.log('后台获取状态:', status); // 执行所有注册的任务 console.log('当前注册的任务数量:', this.tasks.size); this.tasks.forEach((task, id) => { console.log(`- 任务ID: ${id}, 名称: ${task.name}`); }); const results = await this.executeAllTasks(); console.log('任务执行结果:', results); // 显示任务状态 const taskStatuses = this.getAllTaskStatuses(); taskStatuses.forEach(status => { console.log(`任务 ${status.id} 状态:`, { isRegistered: status.isRegistered, executionCount: status.executionCount, lastExecution: status.lastExecution?.toISOString(), lastError: status.lastError }); }); } catch (error) { console.error('调试执行失败:', error); } console.log('=== 调试执行完成 ==='); } } // 导出单例实例 export const backgroundTaskManager = BackgroundTaskManager.getInstance(); // 导出类型 export type { BackgroundTask as BackgroundTaskType, TaskStatus as TaskStatusType };