feat: 集成后台任务管理功能及相关组件

- 新增后台任务管理器,支持任务的注册、执行和状态监控
- 实现自定义Hook,简化后台任务的使用和管理
- 添加示例任务,包括数据同步、健康数据更新和通知检查等
- 更新文档,详细描述后台任务系统的实现和使用方法
- 优化相关组件,确保用户体验和界面一致性
This commit is contained in:
2025-08-24 09:46:11 +08:00
parent 4f2bd76b8f
commit 23aa15f76e
17 changed files with 1289 additions and 119 deletions

View File

@@ -0,0 +1,263 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as ExpoBackgroundTask from 'expo-background-task';
import * as TaskManager from 'expo-task-manager';
// 任务类型定义
export interface BackgroundTask {
id: string;
name: string;
handler: (data?: any) => Promise<void>;
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<string, BackgroundTask> = new Map();
private taskStatuses: Map<string, TaskStatus> = new Map();
private isInitialized = false;
// 单例模式
public static getInstance(): BackgroundTaskManager {
if (!BackgroundTaskManager.instance) {
BackgroundTaskManager.instance = new BackgroundTaskManager();
}
return BackgroundTaskManager.instance;
}
// 初始化后台任务管理器
public async initialize(): Promise<void> {
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<void> {
const BACKGROUND_TASK = 'background-task';
console.log('注册后台任务');
// 定义后台任务
TaskManager.defineTask(BACKGROUND_TASK, async () => {
try {
console.log('开始执行后台任务');
// 执行所有注册的任务
const results = await this.executeAllTasks();
console.log('后台任务执行完成:', results);
// 返回成功状态
return ExpoBackgroundTask.BackgroundTaskResult.Success;
} catch (error) {
console.error('后台任务执行失败:', error);
return ExpoBackgroundTask.BackgroundTaskResult.Failed;
}
});
// 注册后台任务
await ExpoBackgroundTask.registerTaskAsync(BACKGROUND_TASK, {
minimumInterval: 15, // 最小间隔60分钟
});
console.log('后台任务注册成功');
}
// 注册自定义任务
public async registerTask(task: BackgroundTask): Promise<void> {
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<void> {
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<void> {
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<ExpoBackgroundTask.BackgroundTaskStatus | null> {
return await ExpoBackgroundTask.getStatusAsync();
}
// 保存任务状态到本地存储
private async saveTaskStatuses(): Promise<void> {
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<void> {
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<void> {
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();
}
}
// 导出单例实例
export const backgroundTaskManager = BackgroundTaskManager.getInstance();
// 导出类型
export type { BackgroundTask as BackgroundTaskType, TaskStatus as TaskStatusType };

180
services/backgroundTasks.ts Normal file
View File

@@ -0,0 +1,180 @@
import { BackgroundTaskType as BackgroundTask, backgroundTaskManager } from './backgroundTaskManager';
// 示例任务:数据同步任务
export const createDataSyncTask = (): BackgroundTask => ({
id: 'data-sync-task',
name: '数据同步任务',
handler: async (data?: any) => {
console.log('开始执行数据同步任务');
try {
// 这里实现您的数据同步逻辑
// 例如:同步用户数据、运动记录、目标进度等
// 模拟数据同步过程
await new Promise(resolve => setTimeout(resolve, 2000));
console.log('数据同步任务执行完成');
} catch (error) {
console.error('数据同步任务执行失败:', error);
throw error;
}
},
options: {
minimumInterval: 5, // 5分钟最小间隔
stopOnTerminate: false,
startOnBoot: true,
},
});
// 示例任务:健康数据更新任务
export const createHealthDataUpdateTask = (): BackgroundTask => ({
id: 'health-data-update-task',
name: '健康数据更新任务',
handler: async (data?: any) => {
console.log('开始执行健康数据更新任务');
try {
// 这里实现您的健康数据更新逻辑
// 例如:更新步数、心率、体重等健康数据
// 模拟健康数据更新过程
await new Promise(resolve => setTimeout(resolve, 1500));
console.log('健康数据更新任务执行完成');
} catch (error) {
console.error('健康数据更新任务执行失败:', error);
throw error;
}
},
options: {
minimumInterval: 10, // 10分钟最小间隔
stopOnTerminate: false,
startOnBoot: true,
},
});
// 示例任务:通知检查任务
export const createNotificationCheckTask = (): BackgroundTask => ({
id: 'notification-check-task',
name: '通知检查任务',
handler: async (data?: any) => {
console.log('开始执行通知检查任务');
try {
// 这里实现您的通知检查逻辑
// 例如:检查是否需要发送运动提醒、目标达成通知等
// 模拟通知检查过程
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('通知检查任务执行完成');
} catch (error) {
console.error('通知检查任务执行失败:', error);
throw error;
}
},
options: {
minimumInterval: 30, // 30分钟最小间隔
stopOnTerminate: false,
startOnBoot: true,
},
});
// 示例任务:缓存清理任务
export const createCacheCleanupTask = (): BackgroundTask => ({
id: 'cache-cleanup-task',
name: '缓存清理任务',
handler: async (data?: any) => {
console.log('开始执行缓存清理任务');
try {
// 这里实现您的缓存清理逻辑
// 例如:清理过期的图片缓存、临时文件等
// 模拟缓存清理过程
await new Promise(resolve => setTimeout(resolve, 3000));
console.log('缓存清理任务执行完成');
} catch (error) {
console.error('缓存清理任务执行失败:', error);
throw error;
}
},
options: {
minimumInterval: 86400, // 24小时最小间隔
stopOnTerminate: false,
startOnBoot: true,
},
});
// 示例任务:用户行为分析任务
export const createUserAnalyticsTask = (): BackgroundTask => ({
id: 'user-analytics-task',
name: '用户行为分析任务',
handler: async (data?: any) => {
console.log('开始执行用户行为分析任务');
try {
// 这里实现您的用户行为分析逻辑
// 例如:分析用户运动习惯、使用模式等
// 模拟用户行为分析过程
await new Promise(resolve => setTimeout(resolve, 2500));
console.log('用户行为分析任务执行完成');
} catch (error) {
console.error('用户行为分析任务执行失败:', error);
throw error;
}
},
options: {
minimumInterval: 60, // 1小时最小间隔
stopOnTerminate: false,
startOnBoot: true,
},
});
// 注册所有默认任务
export const registerDefaultTasks = async (): Promise<void> => {
try {
const tasks = [
createDataSyncTask(),
createHealthDataUpdateTask(),
createNotificationCheckTask(),
createCacheCleanupTask(),
createUserAnalyticsTask(),
];
for (const task of tasks) {
await backgroundTaskManager.registerTask(task);
}
console.log('所有默认任务注册完成');
} catch (error) {
console.error('注册默认任务失败:', error);
throw error;
}
};
// 创建自定义任务的工厂函数
export const createCustomTask = (
id: string,
name: string,
handler: (data?: any) => Promise<void>,
options?: {
minimumInterval?: number;
stopOnTerminate?: boolean;
startOnBoot?: boolean;
}
): BackgroundTask => ({
id,
name,
handler,
options: {
minimumInterval: 300, // 默认5分钟
stopOnTerminate: false,
startOnBoot: true,
...options,
},
});