Files
frontend/src/services/background/backgroundService.ts
lafay fe6a03da5d
Some checks failed
Frontend CI / build-and-push-web (push) Successful in 2m39s
Frontend CI / ota-android (push) Successful in 10m22s
Frontend CI / build-android-apk (push) Has been cancelled
feat: 优化架构
2026-04-13 01:30:37 +08:00

239 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 后台保活服务
*
* 整合前台服务和后台同步
* - REALTIME 模式:使用 Android 前台服务保活(通知栏常驻)
* - BATTERY_SAVER 模式:使用 expo-background-task 定期同步最小15分钟间隔
*
* 参考Element Android 的 GuardAndroidService + BackgroundSyncStarter
*/
import { Platform } from 'react-native';
import * as BackgroundTask from 'expo-background-task';
import * as TaskManager from 'expo-task-manager';
import {
backgroundSyncManager,
BackgroundSyncMode,
} from './BackgroundSyncManager';
import { messageService } from '../message/messageService';
import { api } from '../core/api';
// 后台任务名称
const BACKGROUND_SYNC_TASK = 'background-sync-task';
// 后台任务间隔(分钟)
const BACKGROUND_INTERVAL_MINUTES = 15;
// 服务状态
let isInitialized = false;
// 定义后台任务(使用 expo-background-task
TaskManager.defineTask(BACKGROUND_SYNC_TASK, async () => {
try {
// 检查是否已认证
const token = await api.getToken();
if (!token) {
return BackgroundTask.BackgroundTaskResult.Success;
}
// 执行同步
await syncMessages();
return BackgroundTask.BackgroundTaskResult.Success;
} catch (error) {
console.error('[BackgroundService] 后台任务执行失败:', error);
return BackgroundTask.BackgroundTaskResult.Failed;
}
});
/**
* 执行消息同步
*/
async function syncMessages(): Promise<void> {
try {
// 同步未读数
const unreadData = await messageService.getUnreadCount();
const totalUnread = unreadData?.total_unread_count ?? 0;
// 更新前台服务通知
await backgroundSyncManager.updateNotification(totalUnread);
console.log('[BackgroundService] 同步完成, 未读数:', totalUnread);
} catch (error) {
console.error('[BackgroundService] 同步失败:', error);
}
}
/**
* 注册后台任务expo-background-task
*/
async function registerBackgroundTask(): Promise<void> {
if (Platform.OS === 'web') {
return;
}
try {
// 检查后台任务状态
const status = await BackgroundTask.getStatusAsync();
if (status !== BackgroundTask.BackgroundTaskStatus.Available) {
console.warn('[BackgroundService] 后台任务不可用,状态:', status);
return;
}
// 检查是否已注册
const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_SYNC_TASK);
if (!isRegistered) {
await BackgroundTask.registerTaskAsync(BACKGROUND_SYNC_TASK, {
minimumInterval: BACKGROUND_INTERVAL_MINUTES, // 以分钟为单位
});
console.log('[BackgroundService] 后台任务已注册');
}
} catch (error) {
console.error('[BackgroundService] 注册后台任务失败:', error);
}
}
/**
* 取消后台任务
*/
async function unregisterBackgroundTask(): Promise<void> {
if (Platform.OS === 'web') {
return;
}
try {
const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_SYNC_TASK);
if (isRegistered) {
await BackgroundTask.unregisterTaskAsync(BACKGROUND_SYNC_TASK);
console.log('[BackgroundService] 后台任务已取消');
}
} catch (error) {
console.error('[BackgroundService] 取消后台任务失败:', error);
}
}
/**
* 初始化后台保活服务
*/
export async function initBackgroundService(): Promise<boolean> {
if (isInitialized) {
return true;
}
if (Platform.OS === 'web') {
isInitialized = true;
return true;
}
try {
// 设置同步回调
backgroundSyncManager.setSyncMessagesCallback(syncMessages);
// 初始化后台同步管理器
await backgroundSyncManager.initialize();
// 注册 expo-background-task 任务(用于 BATTERY_SAVER 模式)
await registerBackgroundTask();
isInitialized = true;
console.log('[BackgroundService] 初始化完成');
return true;
} catch (error) {
console.error('[BackgroundService] 初始化失败:', error);
return false;
}
}
/**
* 停止后台保活服务
*/
export async function stopBackgroundService(): Promise<void> {
try {
await unregisterBackgroundTask();
await backgroundSyncManager.cleanup();
isInitialized = false;
console.log('[BackgroundService] 服务已停止');
} catch (error) {
console.error('[BackgroundService] 停止服务失败:', error);
}
}
/**
* 检查后台服务状态
*/
export async function checkBackgroundStatus(): Promise<{
isAvailable: boolean;
isInitialized: boolean;
registeredTasks: string[];
mode: BackgroundSyncMode;
}> {
if (Platform.OS === 'web') {
return {
isAvailable: false,
isInitialized,
registeredTasks: [],
mode: backgroundSyncManager.getMode(),
};
}
const status = await BackgroundTask.getStatusAsync();
const registeredTasks = await TaskManager.getRegisteredTasksAsync();
return {
isAvailable: status === BackgroundTask.BackgroundTaskStatus.Available,
isInitialized,
registeredTasks: registeredTasks.map((task) => task.taskName),
mode: backgroundSyncManager.getMode(),
};
}
/**
* 设置后台同步模式
*/
export async function setBackgroundSyncMode(mode: BackgroundSyncMode): Promise<void> {
await backgroundSyncManager.setMode(mode);
}
/**
* 获取当前后台同步模式
*/
export function getBackgroundSyncMode(): BackgroundSyncMode {
return backgroundSyncManager.getMode();
}
/**
* 手动触发同步
*/
export async function syncNow(): Promise<void> {
await syncMessages();
}
// 导出震动相关功能(保持向后兼容)
export {
triggerVibration,
vibrateOnMessage,
setVibrationConfig,
getVibrationConfig,
setVibrationEnabled,
} from '../platform/messageVibrationService';
// 重新导出类型
export { BackgroundSyncMode };
// 后台服务实例
export const backgroundService = {
init: initBackgroundService,
stop: stopBackgroundService,
setMode: setBackgroundSyncMode,
getMode: getBackgroundSyncMode,
syncNow,
checkStatus: checkBackgroundStatus,
// 震动相关
vibrate: async () => {
const { triggerVibration } = await import('../platform/messageVibrationService');
triggerVibration();
},
};
export default backgroundService;