DCS/ruiyiweiUX/Assets/Scripts/DCXManager.cs

250 lines
9.0 KiB
C#
Raw Normal View History

2026-06-09 13:59:11 +08:00
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.SceneManagement;
public class DCXManager : MonoBehaviour
{
private SerialCommunicationService _serialService;
// public DataService _dataService;
private UserLogService _userLogService;
// 内存监控相关
private float _lastMemoryCheckTime = 0f;
private const float MEMORY_CHECK_INTERVAL = 60f; // 每分钟检查一次内存
// 网络错误日志限流相关
private float _lastNetworkErrorLogTime = 0f;
private const float NETWORK_ERROR_LOG_INTERVAL = 60f; // 每60秒记录一次网络错误
private int _networkErrorCount = 0;
void Awake()
{
DontDestroyOnLoad(gameObject);
#if UNITY_ANDROID && !UNITY_EDITOR
// 设置服务在Awake阶段加载文件日志也要先启动才能记录启动恢复来源。
InitializeAndroidLogger();
#endif
BootstrapServices();
// 注册Unity日志回调以捕获网络错误
Application.logMessageReceived += HandleUnityLogs;
}
void Start()
{
UIManager.Instance.ShowPanel<StandByPanel>();
}
void Update()
{
// 确保串口服务在主线程中处理接收队列
_serialService?.Update();
// 定期内存检查
CheckMemoryUsage();
}
/// <summary>
/// 定期检查内存使用情况
/// </summary>
private void CheckMemoryUsage()
{
if (Time.time - _lastMemoryCheckTime >= MEMORY_CHECK_INTERVAL)
{
var memoryUsage = System.GC.GetTotalMemory(false) / (1024 * 1024f); // MB
#if UNITY_ANDROID && !UNITY_EDITOR
// 记录内存使用到文件日志
AndroidFileLogger.Instance?.LogMemoryUsage(memoryUsage,
$"队列状态: {_serialService?.GetQueueStatus() ?? ""}");
// 安卓板上内存使用过多时强制清理
if (memoryUsage > 300) // 超过300MB时强制清理
{
AndroidFileLogger.Instance?.LogError("Memory",
$"内存过高({memoryUsage:F1}MB),开始强制清理");
Debug.LogWarning($"[内存警告] 当前内存使用: {memoryUsage:F1}MB开始强制清理");
// 清理串口队列
_serialService?.ForceCleanQueues();
// 强制垃圾回收
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect(); // 二次回收
var memoryAfter = System.GC.GetTotalMemory(false) / (1024 * 1024f);
AndroidFileLogger.Instance?.LogInfo("Memory",
$"清理完成: {memoryUsage:F1}MB -> {memoryAfter:F1}MB, 释放: {(memoryUsage - memoryAfter):F1}MB");
Debug.Log($"[内存清理] 清理后内存: {memoryAfter:F1}MB释放: {(memoryUsage - memoryAfter):F1}MB");
}
else if (memoryUsage > 200) // 超过200MB时记录警告
{
AndroidFileLogger.Instance?.LogInfo("Memory",
$"内存使用较高: {memoryUsage:F1}MB");
Debug.LogWarning($"[内存监控] 内存使用较高: {memoryUsage:F1}MB");
// 每30秒强制执行一次内存清理
if (Time.time % 30f < 1f)
{
_serialService?.MonitorMemoryUsage();
}
}
#else
// PC上只记录内存使用情况
if (memoryUsage > 500)
{
Debug.LogWarning($"[内存监控] 当前内存使用: {memoryUsage:F1}MB");
}
#endif
_lastMemoryCheckTime = Time.time;
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
/// <summary>
/// 初始化安卓文件日志系统
/// </summary>
private void InitializeAndroidLogger()
{
try
{
// AndroidFileLogger会自动创建单例并初始化
var logger = AndroidFileLogger.Instance;
if (logger != null)
{
logger.LogInfo("DCXManager", "安卓文件日志系统已初始化");
logger.LogInfo("DCXManager", $"应用启动时间: {System.DateTime.Now:yyyy-MM-dd HH:mm:ss}");
// 记录初始内存状态
var initialMemory = System.GC.GetTotalMemory(false) / (1024 * 1024f);
logger.LogMemoryUsage(initialMemory, "应用启动");
Debug.Log($"[DCXManager] 安卓文件日志系统已启动,日志路径: {logger.GetCurrentLogFilePath()}");
}
else
{
Debug.LogError("[DCXManager] 安卓文件日志系统初始化失败");
}
}
catch (System.Exception ex)
{
Debug.LogError($"[DCXManager] 初始化安卓文件日志系统异常: {ex.Message}");
}
}
#endif
private void BootstrapServices()
{
// 首先注册数据持久化服务
if (!ServiceLocator.IsRegistered<IDataPersistenceService>())
{
ServiceLocator.Register<IDataPersistenceService>(new DataPersistenceService());
}
if (!ServiceLocator.IsRegistered<IAuthenticationService>())
{
// 使用新的持久化认证服务替代内存版本
ServiceLocator.Register<IAuthenticationService>(new PersistentAuthenticationService());
}
if(!ServiceLocator.IsRegistered<UserLogService>())
{
_userLogService = new UserLogService();
ServiceLocator.Register<UserLogService>(_userLogService);
}
// 注册串口通信服务
if (!ServiceLocator.IsRegistered<ISerialCommunicationService>())
{
_serialService = new SerialCommunicationService();
ServiceLocator.Register<ISerialCommunicationService>(_serialService);
}
if (!ServiceLocator.IsRegistered<ISystemSettingsService>())
{
ServiceLocator.Register<ISystemSettingsService>(new SystemSettingsService());
}
// if (!ServiceLocator.IsRegistered<IPowerService>())
// {
// ServiceLocator.Register<IPowerService>(new PowerService());
// }
if (!ServiceLocator.IsRegistered<IDataExportService>())
{
ServiceLocator.Register<IDataExportService>(new DataExportService());
}
if (!ServiceLocator.IsRegistered<IPatientInfoService>())
{
ServiceLocator.Register<IPatientInfoService>(new PatientInfoService());
}
// if (!ServiceLocator.IsRegistered<IDataService>())
// {
// ServiceLocator.Register<IDataService>(_dataService);
// }
// 注册患者会话服务
if (!ServiceLocator.IsRegistered<PatientSessionService>())
{
ServiceLocator.Register<PatientSessionService>(new PatientSessionService());
}
}
void OnDestroy()
{
// 取消注册日志回调
Application.logMessageReceived -= HandleUnityLogs;
}
/// <summary>
/// 处理Unity日志实现网络错误限流
/// </summary>
private void HandleUnityLogs(string logString, string stackTrace, LogType type)
{
// 只处理Error和Exception类型的日志
if (type != LogType.Error && type != LogType.Exception)
return;
// 检测是否为网络相关错误
bool isNetworkError = logString.Contains("Network is unreachable") ||
logString.Contains("network") ||
logString.Contains("Network");
if (!isNetworkError)
return;
// 网络错误计数
_networkErrorCount++;
// 每60秒记录一次避免日志刷屏
if (Time.time - _lastNetworkErrorLogTime >= NETWORK_ERROR_LOG_INTERVAL)
{
Debug.Log($"[DCXManager] Unity底层网络检查(已忽略): {logString}");
_lastNetworkErrorLogTime = Time.time;
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidFileLogger.Instance?.LogInfo("Network",
$"Unity网络错误(过去{NETWORK_ERROR_LOG_INTERVAL}秒): {_networkErrorCount}次");
// 记录详细信息以便调试
if (_networkErrorCount == 1)
{
AndroidFileLogger.Instance?.LogInfo("Network",
$"首次网络错误详情: {logString}");
}
#endif
// 重置计数器
_networkErrorCount = 0;
}
// 注意不触发GC不做其他重操作
// 网络错误是Unity Native层行为不影响串口通信
}
}