完成修复tcp在app的各种操作,包括 切换,推出重新加入,息屏后重新进入重连失败问题.-已测试成功验证
This commit is contained in:
@@ -49,9 +49,9 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
data: {'user': user, 'data': user}
|
||||
);
|
||||
if (user != null) {
|
||||
tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT);
|
||||
await tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT);
|
||||
// await _authTcpDatasource.sendAuthPacket();//包括发送认证包和获取列表和切换函数
|
||||
tcp.startHeartbeat(interval: const Duration(seconds: 4));
|
||||
tcp.startHeartbeat(interval: const Duration(seconds: 4));
|
||||
// 2. 同步全局 App 状态
|
||||
appCubit.setAuth(user);
|
||||
// 3. 进入已登录状态
|
||||
@@ -142,4 +142,27 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
_kickOutSub?.cancel(); // 销毁 Cubit 时关闭监听
|
||||
return super.close();
|
||||
}
|
||||
|
||||
|
||||
/// 🔥 息屏/后台后恢复到前台时的重连方法
|
||||
Future<void> reconnectAfterResume() async {
|
||||
print('📱 [AUTH] 检测到应用恢复到前台,检查 TCP 连接状态...');
|
||||
|
||||
// 如果 TCP 未连接,则执行重连
|
||||
if (!tcp.isConnected) {
|
||||
print('⚠️ [AUTH] TCP 未连接,开始重连...');
|
||||
try {
|
||||
await tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT);
|
||||
tcp.startHeartbeat(interval: const Duration(seconds: 4));
|
||||
print('✅ [AUTH] TCP 重连成功!');
|
||||
} catch (e) {
|
||||
print('❌ [AUTH] TCP 重连失败:$e');
|
||||
// 可以选择重试或者通知用户
|
||||
}
|
||||
} else {
|
||||
print('✅ [AUTH] TCP 连接正常,无需重连');
|
||||
// 可选:发送一个心跳包确认连接有效
|
||||
tcp.sendHeartbeat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:maibu_satabot_v2/features/auth/presentation/bloc/auth_cubit.dart
|
||||
import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_cubit.dart';
|
||||
|
||||
import 'core/di/injection.dart';
|
||||
import 'features/auth/presentation/bloc/auth_state.dart';
|
||||
import 'features/auth/presentation/bloc/login_cubit.dart';
|
||||
import 'features/devices/presentation/bloc/device_status_bloc.dart';
|
||||
|
||||
@@ -71,7 +72,101 @@ class MyApp extends StatelessWidget {
|
||||
),
|
||||
// 其他 Cubit...
|
||||
],
|
||||
child: MaterialApp.router(title: 'Maibu Satabot', theme: AppTheme.lightTheme, routerConfig: sl<GoRouter>()),
|
||||
child: MaterialApp.router(title: 'Maibu Satabot', theme: AppTheme.lightTheme, routerConfig: sl<GoRouter>(),
|
||||
builder: (context, child) {
|
||||
return _LifecycleListener(child: child);
|
||||
},),
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
// 🔥 新增:应用生命周期监听器
|
||||
class _LifecycleListener extends StatefulWidget {
|
||||
final Widget? child;
|
||||
|
||||
const _LifecycleListener({required this.child});
|
||||
|
||||
@override
|
||||
State<_LifecycleListener> createState() => _LifecycleListenerState();
|
||||
}
|
||||
|
||||
class _LifecycleListenerState extends State<_LifecycleListener> with WidgetsBindingObserver {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
super.didChangeAppLifecycleState(state);
|
||||
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
// 🔥 从息屏或后台恢复到前台
|
||||
debugPrint('📱 [生命周期] 应用恢复到前台 (resumed),检查 TCP 连接...');
|
||||
_handleResume();
|
||||
break;
|
||||
|
||||
case AppLifecycleState.inactive:
|
||||
// 应用处于非活动状态(iOS 来电、Android 分屏等)
|
||||
debugPrint('💤 [生命周期] 应用进入非活动状态 (inactive)');
|
||||
break;
|
||||
|
||||
case AppLifecycleState.paused:
|
||||
// 应用进入后台(息屏、按 Home 键等)
|
||||
debugPrint('🌙 [生命周期] 应用进入后台 (paused)');
|
||||
break;
|
||||
|
||||
case AppLifecycleState.detached:
|
||||
// 应用仍然托管但不会显示给用户(例如销毁中的 Activity)
|
||||
debugPrint('🚫 [生命周期] 应用已分离 (detached)');
|
||||
break;
|
||||
|
||||
case AppLifecycleState.hidden:
|
||||
// 应用不可见(Android 14+ 或未来版本)
|
||||
debugPrint('👻 [生命周期] 应用已隐藏 (hidden)');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 🔥 处理恢复到前台的逻辑
|
||||
Future<void> _handleResume() async {
|
||||
try {
|
||||
final authCubit = context.read<AuthCubit>();
|
||||
|
||||
// 检查当前是否已登录
|
||||
if (authCubit.state is! AuthAuthenticated) {
|
||||
debugPrint('⚠️ [生命周期] 用户未登录,跳过 TCP 重连');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查 TCP 连接状态
|
||||
// 注意:这里需要通过 authCubit 访问 tcp 实例
|
||||
// 由于 tcp 是 private 字段,我们需要在 AuthCubit 中暴露一个方法
|
||||
debugPrint('✅ [生命周期] 准备执行 TCP 重连检查...');
|
||||
|
||||
// 延迟一点执行,确保 UI 已经加载完成
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// 调用 AuthCubit 的重连方法
|
||||
await authCubit.reconnectAfterResume();
|
||||
|
||||
debugPrint('✅ [生命周期] TCP 重连检查完成');
|
||||
} catch (e, stack) {
|
||||
debugPrint('❌ [生命周期] 重连过程发生错误:$e\n$stack');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.child!;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user