// lib/services/app_lifecycle_manager.dart import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:media_kit/media_kit.dart'; /// App 生命周期状态(扩展了 Flutter 原生状态) enum AppLifecycleStatus { /// 应用正在启动(初始化阶段) launching, /// 应用在前台,用户可交互 resumed, /// 应用在前台但不可交互(如:来电、系统弹窗) inactive, /// 应用在后台 paused, /// 应用即将被销毁 detached, /// 应用已进入后台且播放停止(自定义,用于播放策略) backgroundIdle, } /// App 生命周期管理器 /// /// 职责: /// 1. 统一监听 Flutter 的 AppLifecycleState /// 2. 管理播放器在前后台的行为 /// 3. 管理渲染调度器的运行状态 /// 4. 管理 WebDAV 的缓存策略 class AppLifecycleManager extends ChangeNotifier { static final AppLifecycleManager _instance = AppLifecycleManager._internal(); factory AppLifecycleManager() => _instance; AppLifecycleManager._internal(); // ---- 当前状态 ---- AppLifecycleStatus _status = AppLifecycleStatus.launching; AppLifecycleStatus get status => _status; // ---- 上次进入后台的时间 ---- DateTime? _backgroundedAt; DateTime? get backgroundedAt => _backgroundedAt; // ---- 是否在后台 ---- bool get isInBackground => _status == AppLifecycleStatus.paused || _status == AppLifecycleStatus.inactive || _status == AppLifecycleStatus.detached; bool get isInForeground => _status == AppLifecycleStatus.resumed; // ---- 后台时长 ---- Duration get backgroundDuration { if (_backgroundedAt == null) return Duration.zero; return DateTime.now().difference(_backgroundedAt!); } // ---- 是否处于"长后台"(超过 5 分钟) ---- bool get isLongBackground => backgroundDuration > const Duration(minutes: 5); // ---- 监听器 ---- final List _listeners = []; // ---- Flutter 原生生命周期订阅 ---- late final WidgetsBindingObserver _observer; bool _isObserving = false; // ---- 初始化 ---- void init() { if (_isObserving) return; _isObserving = true; _observer = _AppLifecycleObserver(this); WidgetsBinding.instance.addObserver(_observer); // 获取初始状态 _updateStatus(AppLifecycleStatus.resumed); debugPrint('📱 AppLifecycleManager 已初始化'); } // ---- 状态更新 ---- void _handleNativeState(AppLifecycleState state) { final newStatus = _convertNativeState(state); // 状态变化时更新 if (newStatus != _status) { _updateStatus(newStatus); } // 记录进入后台的时间 if (newStatus == AppLifecycleStatus.paused || newStatus == AppLifecycleStatus.inactive) { if (_backgroundedAt == null) { _backgroundedAt = DateTime.now(); debugPrint('📱 App 进入后台: ${_backgroundedAt}'); } } // 回到前台时,如果是长后台,触发通知 if (newStatus == AppLifecycleStatus.resumed) { if (_backgroundedAt != null) { final duration = backgroundDuration; debugPrint('📱 App 回到前台,后台时长: ${duration.inMinutes}分钟'); _backgroundedAt = null; // 如果是长后台,通知监听器做重连等操作 if (duration > const Duration(minutes: 5)) { _notifyListeners(AppLifecycleStatus.backgroundIdle); } } } } void _updateStatus(AppLifecycleStatus newStatus) { final oldStatus = _status; _status = newStatus; debugPrint('📱 生命周期状态变化: $oldStatus → $newStatus'); notifyListeners(); _notifyListeners(newStatus); } AppLifecycleStatus _convertNativeState(AppLifecycleState state) { switch (state) { case AppLifecycleState.resumed: return AppLifecycleStatus.resumed; case AppLifecycleState.inactive: return AppLifecycleStatus.inactive; case AppLifecycleState.paused: return AppLifecycleStatus.paused; case AppLifecycleState.detached: return AppLifecycleStatus.detached; default: return AppLifecycleStatus.paused; } } // ---- 自定义监听器管理 ---- void addListenerToManager(void Function(AppLifecycleStatus) listener) { _listeners.add(listener); } void removeListenerFromManager(void Function(AppLifecycleStatus) listener) { _listeners.remove(listener); } void _notifyListeners(AppLifecycleStatus status) { for (final listener in _listeners) { try { listener(status); } catch (e) { debugPrint('❌ 生命周期监听器执行失败: $e'); } } } // ---- 检查是否需要重新连接 WebDAV ---- bool get shouldRecheckWebDAV { if (!isInForeground) return false; if (_backgroundedAt == null) return false; return isLongBackground; } // ---- 释放 ---- void dispose() { if (_isObserving) { WidgetsBinding.instance.removeObserver(_observer); _isObserving = false; } _listeners.clear(); super.dispose(); } } /// 内部观察者(绑定 WidgetsBinding) class _AppLifecycleObserver extends WidgetsBindingObserver { final AppLifecycleManager _manager; _AppLifecycleObserver(this._manager); @override void didChangeAppLifecycleState(AppLifecycleState state) { _manager._handleNativeState(state); } }