Browse Source

add 24 hour running needs & add utilcode 1.30.7

main
MTing 2 weeks ago
parent
commit
840316d5e8
  1. 3
      .vscode/settings.json
  2. 34
      app/build.gradle
  3. 20
      app/src/main/AndroidManifest.xml
  4. 45
      app/src/main/java/com/ouxuan/oxface/MainActivity.java
  5. 284
      app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java
  6. 90
      app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java
  7. 328
      app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java
  8. 294
      app/src/main/java/com/ouxuan/oxface/utils/GlobalExceptionHandler.java
  9. 406
      app/src/main/java/com/ouxuan/oxface/utils/HealthMonitor.java
  10. 241
      app/src/main/java/com/ouxuan/oxface/utils/KeepAliveManager.java
  11. 375
      app/src/main/java/com/ouxuan/oxface/utils/LogManager.java
  12. 533
      app/src/main/java/com/ouxuan/oxface/utils/MaintenanceScheduler.java
  13. 245
      app/src/main/java/com/ouxuan/oxface/utils/MemoryManager.java
  14. 382
      app/src/main/java/com/ouxuan/oxface/utils/UtilCodeHelper.java
  15. 16
      gradle.properties

3
.vscode/settings.json

@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "automatic"
}

34
app/build.gradle

@ -15,12 +15,43 @@ android {
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// 24
multiDexEnabled true
}
// Dex优化由Android Gradle插件自动管理
// dexOptions已在Gradle 8.0
//
packagingOptions {
pickFirst '**/libnative-lib.so'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
} }
buildTypes { buildTypes {
debug {
minifyEnabled false
debuggable true
applicationIdSuffix ".debug"
versionNameSuffix "-debug"
//
crunchPngs false
zipAlignEnabled true
}
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//
zipAlignEnabled true
shrinkResources false
} }
} }
@ -45,6 +76,9 @@ dependencies {
// //
implementation 'com.github.bumptech.glide:glide:4.16.0' implementation 'com.github.bumptech.glide:glide:4.16.0'
// Android开发工具库
implementation 'com.blankj:utilcode:1.30.7'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

20
app/src/main/AndroidManifest.xml

@ -5,10 +5,22 @@
<!-- 网络权限 --> <!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 24小时无人值守所需权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application <application
android:name=".OxFaceApplication" android:name=".OxFaceApplication"
android:allowBackup="true"
android:allowBackup="false"
android:largeHeap="true"
android:hardwareAccelerated="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -16,11 +28,15 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.OxFaceLogin" android:theme="@style/Theme.OxFaceLogin"
android:requestLegacyExternalStorage="true"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:theme="@style/Theme.OxFaceLogin.Splash">
android:theme="@style/Theme.OxFaceLogin.Splash"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:configChanges="orientation|screenSize|keyboardHidden">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />

45
app/src/main/java/com/ouxuan/oxface/MainActivity.java

@ -29,6 +29,9 @@ import com.ouxuan.oxface.network.api.PadApiService;
import com.ouxuan.oxface.network.api.UserApiService; import com.ouxuan.oxface.network.api.UserApiService;
import com.ouxuan.oxface.network.callback.NetworkCallback; import com.ouxuan.oxface.network.callback.NetworkCallback;
import com.ouxuan.oxface.network.utils.NetworkUtils; import com.ouxuan.oxface.network.utils.NetworkUtils;
import com.ouxuan.oxface.utils.KeepAliveManager;
import com.ouxuan.oxface.utils.LogManager;
import com.ouxuan.oxface.utils.UtilCodeHelper;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@ -39,6 +42,7 @@ public class MainActivity extends AppCompatActivity {
private Toast currentToast; // 用于管理Toast显示状态 private Toast currentToast; // 用于管理Toast显示状态
private boolean isPasswordVisible = false; // 密码显示状态 private boolean isPasswordVisible = false; // 密码显示状态
private LoginDataManager loginDataManager; // 登录数据管理器 private LoginDataManager loginDataManager; // 登录数据管理器
private KeepAliveManager keepAliveManager; // 保持活跃管理器
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -59,6 +63,13 @@ public class MainActivity extends AppCompatActivity {
// 初始化登录数据管理器 // 初始化登录数据管理器
loginDataManager = LoginDataManager.getInstance(this); loginDataManager = LoginDataManager.getInstance(this);
// 初始化保持活跃管理器并启动用于24小时无人值守
keepAliveManager = KeepAliveManager.getInstance(this);
keepAliveManager.startKeepAlive(this);
// 记录应用启动
LogManager.logOperation("MainActivity", "主界面已初始化,开始24小时无人值守模式");
// 检查是否可以自动登录 // 检查是否可以自动登录
checkAutoLogin(); checkAutoLogin();
@ -633,5 +644,39 @@ public class MainActivity extends AppCompatActivity {
.putString("session_token", selectResponse.getSessionToken()) .putString("session_token", selectResponse.getSessionToken())
.putLong("valid_until", selectResponse.getValidUntil()) .putLong("valid_until", selectResponse.getValidUntil())
.apply(); .apply();
LogManager.logOperation("MainActivity", "已保存选中的设备信息: " + padInfo.getPadName());
}
@Override
protected void onResume() {
super.onResume();
// 确保保持活跃功能正常运行
if (keepAliveManager != null && !keepAliveManager.isKeepingAlive()) {
keepAliveManager.startKeepAlive(this);
LogManager.logOperation("MainActivity", "恢复保持活跃状态");
}
}
@Override
protected void onPause() {
super.onPause();
// 24小时无人值守模式下不停止保持活跃功能
LogManager.logDebug("MainActivity", "应用进入后台,但保持活跃状态继续运行");
}
@Override
protected void onDestroy() {
super.onDestroy();
LogManager.logOperation("MainActivity", "主界面正在销毁");
// 只在应用真正退出时才停止保持活跃
if (isFinishing() && keepAliveManager != null) {
keepAliveManager.stopKeepAlive(this);
LogManager.logOperation("MainActivity", "应用退出,停止保持活跃功能");
}
} }
} }

284
app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java

@ -2,19 +2,295 @@ package com.ouxuan.oxface;
import android.app.Application; import android.app.Application;
import com.ouxuan.oxface.network.NetworkManager;
import com.ouxuan.oxface.network.NetworkStabilityManager;
import com.ouxuan.oxface.network.utils.NetworkUtils; import com.ouxuan.oxface.network.utils.NetworkUtils;
import com.ouxuan.oxface.utils.GlobalExceptionHandler;
import com.ouxuan.oxface.utils.HealthMonitor;
import com.ouxuan.oxface.utils.LogManager;
import com.ouxuan.oxface.utils.MaintenanceScheduler;
import com.ouxuan.oxface.utils.MemoryManager;
import com.ouxuan.oxface.utils.UtilCodeHelper;
import com.blankj.utilcode.util.Utils;
/** /**
* 应用程序Application类 * 应用程序Application类
* 用于全局初始化各种模块
* 用于全局初始化各种模块支持24小时无人值守运行
*/ */
public class OxFaceApplication extends Application {
public class OxFaceApplication extends Application implements
NetworkStabilityManager.NetworkStateListener,
HealthMonitor.HealthStatusListener {
private static final String TAG = "OxFaceApplication";
private static OxFaceApplication instance;
// 管理器实例
private LogManager logManager;
private GlobalExceptionHandler exceptionHandler;
private MemoryManager memoryManager;
private NetworkManager networkManager;
private HealthMonitor healthMonitor;
private MaintenanceScheduler maintenanceScheduler;
public static OxFaceApplication getInstance() {
return instance;
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
instance = this;
// 按顺序初始化所有管理器
initializeManagers();
}
/**
* 初始化所有管理器
*/
private void initializeManagers() {
try {
// 0. 初始化UtilCode工具库最高优先级
Utils.init(this);
// 1. 首先启动日志管理器
initLogManager();
// 2. 安装全局异常处理器
initGlobalExceptionHandler();
// 3. 初始化网络管理器
initNetworkManager();
// 4. 初始化内存管理器
initMemoryManager();
// 5. 初始化健康监控器
initHealthMonitor();
// 6. 启动维护调度器
initMaintenanceScheduler();
// 7. 初始化原有的网络工具
NetworkUtils.init(this);
LogManager.logOperation(TAG, "所有管理器初始化完成,应用已准备好24小时无人值守运行");
} catch (Exception e) {
android.util.Log.e(TAG, "初始化管理器失败", e);
}
}
/**
* 初始化日志管理器
*/
private void initLogManager() {
logManager = LogManager.getInstance(this);
logManager.start();
LogManager.logOperation(TAG, "日志管理器启动");
}
/**
* 初始化全局异常处理器
*/
private void initGlobalExceptionHandler() {
exceptionHandler = new GlobalExceptionHandler(this, true);
exceptionHandler.install();
LogManager.logOperation(TAG, "全局异常处理器安装完成");
}
/**
* 初始化网络管理器
*/
private void initNetworkManager() {
networkManager = NetworkManager.getInstance(this);
networkManager.startNetworkMonitoring(this);
LogManager.logOperation(TAG, "网络管理器初始化完成");
}
/**
* 初始化内存管理器
*/
private void initMemoryManager() {
memoryManager = MemoryManager.getInstance(this);
memoryManager.startMemoryMonitoring();
LogManager.logOperation(TAG, "内存管理器启动");
}
/**
* 初始化健康监控器
*/
private void initHealthMonitor() {
healthMonitor = HealthMonitor.getInstance(this);
healthMonitor.startHealthCheck(this);
LogManager.logOperation(TAG, "健康监控器启动");
}
/**
* 初始化维护调度器
*/
private void initMaintenanceScheduler() {
maintenanceScheduler = MaintenanceScheduler.getInstance(this);
maintenanceScheduler.startMaintenance();
LogManager.logOperation(TAG, "维护调度器启动");
}
// ========== NetworkStateListener 接口实现 ==========
@Override
public void onNetworkAvailable() {
LogManager.logOperation(TAG, "网络连接恢复");
// 重新初始化网络管理器
if (networkManager != null) {
networkManager.reinitialize();
}
}
@Override
public void onNetworkLost() {
LogManager.logWarning(TAG, "网络连接丢失");
}
@Override
public void onNetworkQualityChanged(NetworkStabilityManager.NetworkQuality quality) {
LogManager.logInfo(TAG, "网络质量变化: " + quality);
}
// ========== HealthStatusListener 接口实现 ==========
@Override
public void onHealthStatusChanged(HealthMonitor.HealthStatus status) {
LogManager.logOperation(TAG, "系统健康状态变化: " + status);
if (status == HealthMonitor.HealthStatus.CRITICAL ||
status == HealthMonitor.HealthStatus.SYSTEM_ERROR) {
// 触发紧急维护
if (maintenanceScheduler != null) {
maintenanceScheduler.performImmediateMaintenance();
}
}
}
@Override
public void onCriticalIssueDetected(String issue) {
LogManager.logError(TAG, "检测到严重问题: " + issue);
// 记录系统状态快照
recordSystemSnapshot("严重问题: " + issue);
}
@Override
public void onSystemRecovered(String recoveryAction) {
LogManager.logOperation(TAG, "系统已恢复: " + recoveryAction);
}
/**
* 记录系统状态快照
*/
private void recordSystemSnapshot(String reason) {
try {
StringBuilder snapshot = new StringBuilder();
snapshot.append("=== 系统状态快照 (").append(reason).append(") ===").append("\n");
// 使用UtilCode获取系统信息
snapshot.append("设备信息: ").append(UtilCodeHelper.Device.getDeviceInfoSummary()).append("\n");
snapshot.append("屏幕信息: ").append(UtilCodeHelper.Screen.getScreenInfoSummary()).append("\n");
snapshot.append("网络状态: ").append(UtilCodeHelper.Network.getNetworkStatusSummary()).append("\n");
snapshot.append("应用信息: ").append(UtilCodeHelper.App.getAppInfoSummary()).append("\n");
snapshot.append("当前时间: ").append(UtilCodeHelper.Time.millis2String(UtilCodeHelper.Time.getCurrentTimeMillis())).append("\n");
// 内存状态
if (memoryManager != null) {
snapshot.append("内存使用率: ").append(String.format("%.1f%%", memoryManager.getCurrentMemoryUsage() * 100)).append("\n");
}
// 网络状态详细信息
if (networkManager != null) {
snapshot.append("网络连接: ").append(networkManager.isNetworkAvailable() ? "可用" : "不可用").append("\n");
snapshot.append("网络类型: ").append(networkManager.getNetworkTypeDescription()).append("\n");
}
// 健康状态
if (healthMonitor != null) {
HealthMonitor.HealthReport report = healthMonitor.getCurrentHealthReport();
snapshot.append("系统健康状态: ").append(report.overallStatus).append("\n");
snapshot.append("运行时间: ").append(report.uptime / (1000 * 60 * 60)).append("小时").append("\n");
}
// 维护统计
if (maintenanceScheduler != null) {
snapshot.append("维护统计: ").append(maintenanceScheduler.getMaintenanceStats()).append("\n");
}
snapshot.append("===========================================");
LogManager.logOperation(TAG, snapshot.toString());
} catch (Exception e) {
LogManager.logError(TAG, "记录系统快照失败", e);
}
}
/**
* 优雅关闭所有管理器
*/
@Override
public void onTerminate() {
super.onTerminate();
LogManager.logOperation(TAG, "应用程序正在关闭,停止所有管理器");
try {
// 停止维护调度器
if (maintenanceScheduler != null) {
maintenanceScheduler.stopMaintenance();
}
// 停止健康监控器
if (healthMonitor != null) {
healthMonitor.stopHealthCheck();
}
// 停止内存监控
if (memoryManager != null) {
memoryManager.stopMemoryMonitoring();
}
// 停止网络监控
if (networkManager != null) {
networkManager.stopNetworkMonitoring();
}
// 停止日志管理器最后停止
if (logManager != null) {
logManager.stop();
}
} catch (Exception e) {
android.util.Log.e(TAG, "关闭管理器时发生异常", e);
}
}
// ========== 公共访问方法 ==========
public LogManager getLogManager() {
return logManager;
}
public MemoryManager getMemoryManager() {
return memoryManager;
}
public NetworkManager getNetworkManager() {
return networkManager;
}
public HealthMonitor getHealthMonitor() {
return healthMonitor;
}
// 初始化网络模块
NetworkUtils.init(this);
public MaintenanceScheduler getMaintenanceScheduler() {
return maintenanceScheduler;
} }
} }

90
app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java

@ -10,6 +10,7 @@ import com.ouxuan.oxface.network.callback.NetworkCallback;
import com.ouxuan.oxface.network.interceptor.HeaderInterceptor; import com.ouxuan.oxface.network.interceptor.HeaderInterceptor;
import com.ouxuan.oxface.network.interceptor.NetworkDebugInterceptor; import com.ouxuan.oxface.network.interceptor.NetworkDebugInterceptor;
import com.ouxuan.oxface.network.model.ApiResponse; import com.ouxuan.oxface.network.model.ApiResponse;
import com.ouxuan.oxface.utils.LogManager;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -27,20 +28,28 @@ import retrofit2.converter.gson.GsonConverterFactory;
/** /**
* 网络请求管理器 * 网络请求管理器
* 单例模式统一管理所有网络请求 * 单例模式统一管理所有网络请求
* 集成网络稳定性优化功能适用于24小时无人值守环境
*/ */
public class NetworkManager { public class NetworkManager {
private static final String TAG = "NetworkManager";
private static volatile NetworkManager instance; private static volatile NetworkManager instance;
private OkHttpClient okHttpClient; private OkHttpClient okHttpClient;
private Retrofit retrofit; private Retrofit retrofit;
private Gson gson; private Gson gson;
private Handler mainHandler; private Handler mainHandler;
private Context context;
private NetworkStabilityManager networkStabilityManager;
private NetworkManager(Context context) { private NetworkManager(Context context) {
this.context = context.getApplicationContext();
this.networkStabilityManager = NetworkStabilityManager.getInstance(this.context);
initOkHttpClient(context); initOkHttpClient(context);
initRetrofit(); initRetrofit();
initGson(); initGson();
mainHandler = new Handler(Looper.getMainLooper()); mainHandler = new Handler(Looper.getMainLooper());
LogManager.logOperation("NetworkManager", "网络管理器初始化完成");
} }
/** /**
@ -60,13 +69,25 @@ public class NetworkManager {
} }
/** /**
* 初始化OkHttpClient
* 获取NetworkManager单例实例需要先调用getInstance(Context)初始化
* @return NetworkManager实例
*/
public static NetworkManager getInstance() {
if (instance == null) {
throw new IllegalStateException("NetworkManager 未初始化,请先调用 getInstance(Context)");
}
return instance;
}
/**
* 初始化OkHttpClient集成网络稳定性优化
*/ */
private void initOkHttpClient(Context context) { private void initOkHttpClient(Context context) {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(NetworkConfig.CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(NetworkConfig.READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(NetworkConfig.WRITE_TIMEOUT, TimeUnit.SECONDS)
// 使用网络稳定性管理器的增强OkHttpClient配置
OkHttpClient enhancedClient = networkStabilityManager.getEnhancedOkHttpClient();
// 在增强配置的基础上添加项目特定的拦截器
OkHttpClient.Builder builder = enhancedClient.newBuilder()
.addInterceptor(new HeaderInterceptor(context)); .addInterceptor(new HeaderInterceptor(context));
// 添加网络调试拦截器优先级最高在所有拦截器之前 // 添加网络调试拦截器优先级最高在所有拦截器之前
@ -82,6 +103,8 @@ public class NetworkManager {
} }
okHttpClient = builder.build(); okHttpClient = builder.build();
LogManager.logOperation("NetworkManager", "增强OkHttpClient配置完成");
} }
/** /**
@ -225,4 +248,61 @@ public class NetworkManager {
} }
}); });
} }
/**
* 重新初始化网络管理器用于网络恢复后的重置
*/
public void reinitialize() {
try {
LogManager.logOperation("NetworkManager", "开始重新初始化网络管理器");
// 重新初始化OkHttpClient
initOkHttpClient(context);
// 重新初始化Retrofit
initRetrofit();
LogManager.logOperation("NetworkManager", "网络管理器重新初始化完成");
} catch (Exception e) {
LogManager.logError(TAG, "网络管理器重新初始化失败", e);
}
}
/**
* 获取网络稳定性管理器
*/
public NetworkStabilityManager getNetworkStabilityManager() {
return networkStabilityManager;
}
/**
* 检查网络是否可用
*/
public boolean isNetworkAvailable() {
return networkStabilityManager.isNetworkAvailable();
}
/**
* 获取网络类型描述
*/
public String getNetworkTypeDescription() {
return networkStabilityManager.getNetworkTypeDescription();
}
/**
* 启动网络状态监控
*/
public void startNetworkMonitoring(NetworkStabilityManager.NetworkStateListener listener) {
networkStabilityManager.startNetworkMonitoring(listener);
LogManager.logOperation("NetworkManager", "网络状态监控已启动");
}
/**
* 停止网络状态监控
*/
public void stopNetworkMonitoring() {
networkStabilityManager.stopNetworkMonitoring();
LogManager.logOperation("NetworkManager", "网络状态监控已停止");
}
} }

328
app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java

@ -0,0 +1,328 @@
package com.ouxuan.oxface.network;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.util.Log;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* 网络稳定性管理器
* 用于24小时无人值守环境下的网络连接稳定性保障
*/
public class NetworkStabilityManager {
private static final String TAG = "NetworkStabilityManager";
private static final int MAX_RETRY_COUNT = 3;
private static final int RETRY_DELAY_MS = 5000;
private static final int CONNECT_TIMEOUT_SECONDS = 30;
private static final int READ_TIMEOUT_SECONDS = 60;
private static final int WRITE_TIMEOUT_SECONDS = 60;
private static NetworkStabilityManager instance;
private Context context;
private ConnectivityManager connectivityManager;
private ConnectivityManager.NetworkCallback networkCallback;
private boolean isMonitoring = false;
private NetworkStateListener networkStateListener;
public interface NetworkStateListener {
void onNetworkAvailable();
void onNetworkLost();
void onNetworkQualityChanged(NetworkQuality quality);
}
public enum NetworkQuality {
EXCELLENT, GOOD, POOR, VERY_POOR
}
private NetworkStabilityManager(Context context) {
this.context = context.getApplicationContext();
this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
public static synchronized NetworkStabilityManager getInstance(Context context) {
if (instance == null) {
instance = new NetworkStabilityManager(context);
}
return instance;
}
/**
* 获取增强的OkHttpClient配置
*/
public OkHttpClient getEnhancedOkHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(CONNECT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new RetryInterceptor(MAX_RETRY_COUNT))
.addInterceptor(new NetworkQualityInterceptor())
.build();
}
/**
* 开始网络状态监控
*/
public void startNetworkMonitoring(NetworkStateListener listener) {
if (isMonitoring) {
return;
}
this.networkStateListener = listener;
isMonitoring = true;
if (connectivityManager != null) {
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
Log.i(TAG, "网络连接恢复: " + network.toString());
if (networkStateListener != null) {
networkStateListener.onNetworkAvailable();
}
}
@Override
public void onLost(Network network) {
super.onLost(network);
Log.w(TAG, "网络连接丢失: " + network.toString());
if (networkStateListener != null) {
networkStateListener.onNetworkLost();
}
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
// 检查网络质量
NetworkQuality quality = evaluateNetworkQuality(networkCapabilities);
Log.d(TAG, "网络质量变化: " + quality);
if (networkStateListener != null) {
networkStateListener.onNetworkQualityChanged(quality);
}
}
};
NetworkRequest.Builder builder = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
connectivityManager.registerNetworkCallback(builder.build(), networkCallback);
Log.i(TAG, "网络状态监控已启动");
}
}
/**
* 停止网络状态监控
*/
public void stopNetworkMonitoring() {
if (isMonitoring && connectivityManager != null && networkCallback != null) {
try {
connectivityManager.unregisterNetworkCallback(networkCallback);
isMonitoring = false;
Log.i(TAG, "网络状态监控已停止");
} catch (Exception e) {
Log.e(TAG, "停止网络监控失败", e);
}
}
}
/**
* 检查网络是否可用
*/
public boolean isNetworkAvailable() {
if (connectivityManager == null) {
return false;
}
Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork == null) {
return false;
}
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
return capabilities != null &&
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
/**
* 评估网络质量
*/
private NetworkQuality evaluateNetworkQuality(NetworkCapabilities capabilities) {
if (capabilities == null) {
return NetworkQuality.VERY_POOR;
}
// 基于网络类型和能力评估质量
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
if (capabilities.getLinkDownstreamBandwidthKbps() > 10000) { // > 10Mbps
return NetworkQuality.EXCELLENT;
} else if (capabilities.getLinkDownstreamBandwidthKbps() > 5000) { // > 5Mbps
return NetworkQuality.GOOD;
} else {
return NetworkQuality.POOR;
}
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return NetworkQuality.GOOD;
} else {
return NetworkQuality.POOR;
}
}
/**
* 获取网络类型描述
*/
public String getNetworkTypeDescription() {
if (!isNetworkAvailable()) {
return "无网络连接";
}
Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
if (capabilities == null) {
return "未知网络";
}
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
return "以太网";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return "WiFi";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return "移动网络";
} else {
return "其他网络";
}
}
/**
* 重试拦截器
*/
public static class RetryInterceptor implements Interceptor {
private int maxRetryCount;
public RetryInterceptor(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException lastException = null;
for (int retryCount = 0; retryCount <= maxRetryCount; retryCount++) {
try {
response = chain.proceed(request);
// 如果响应成功直接返回
if (response.isSuccessful()) {
if (retryCount > 0) {
Log.i(TAG, "重试成功,重试次数: " + retryCount);
}
return response;
}
// 如果是服务器错误且不是最后一次重试关闭响应并重试
if (retryCount < maxRetryCount && response.code() >= 500) {
response.close();
Log.w(TAG, "服务器错误 " + response.code() + ",准备重试 " + (retryCount + 1));
// 等待一段时间再重试
try {
Thread.sleep(RETRY_DELAY_MS * (retryCount + 1));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("重试被中断", e);
}
} else {
return response;
}
} catch (IOException e) {
lastException = e;
if (retryCount < maxRetryCount) {
Log.w(TAG, "网络请求失败,准备重试 " + (retryCount + 1) + ": " + e.getMessage());
// 等待一段时间再重试
try {
Thread.sleep(RETRY_DELAY_MS * (retryCount + 1));
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("重试被中断", ie);
}
}
}
}
// 所有重试都失败了
Log.e(TAG, "网络请求重试 " + maxRetryCount + " 次后仍然失败");
if (lastException != null) {
throw lastException;
} else {
return response;
}
}
}
/**
* 网络质量监控拦截器
*/
public class NetworkQualityInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
long startTime = System.currentTimeMillis();
try {
Response response = chain.proceed(chain.request());
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
// 记录网络质量信息
logNetworkQuality(responseTime, true);
return response;
} catch (IOException e) {
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
// 记录网络质量信息
logNetworkQuality(responseTime, false);
throw e;
}
}
private void logNetworkQuality(long responseTime, boolean success) {
String status = success ? "成功" : "失败";
if (responseTime > 30000) { // 超过30秒
Log.e(TAG, String.format("网络响应极慢 %s: %dms", status, responseTime));
} else if (responseTime > 10000) { // 超过10秒
Log.w(TAG, String.format("网络响应缓慢 %s: %dms", status, responseTime));
} else if (responseTime > 3000) { // 超过3秒
Log.i(TAG, String.format("网络响应较慢 %s: %dms", status, responseTime));
} else {
Log.d(TAG, String.format("网络响应正常 %s: %dms", status, responseTime));
}
}
}
}

294
app/src/main/java/com/ouxuan/oxface/utils/GlobalExceptionHandler.java

@ -0,0 +1,294 @@
package com.ouxuan.oxface.utils;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.ouxuan.oxface.MainActivity;
import com.ouxuan.oxface.network.NetworkStabilityManager;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 全局异常处理器
* 用于24小时无人值守环境下的异常捕获和应用自动恢复
*/
public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = "GlobalExceptionHandler";
private static final String CRASH_LOG_DIR = "crash_logs";
private static final String CRASH_LOG_PREFIX = "crash_";
private static final int MAX_CRASH_LOGS = 10; // 最多保留10个崩溃日志文件
private static final long RESTART_DELAY = 3000; // 重启延迟3秒
private Thread.UncaughtExceptionHandler defaultHandler;
private Context context;
private boolean enableAutoRestart;
public GlobalExceptionHandler(Context context) {
this(context, true);
}
public GlobalExceptionHandler(Context context, boolean enableAutoRestart) {
this.context = context.getApplicationContext();
this.enableAutoRestart = enableAutoRestart;
this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
}
/**
* 初始化全局异常处理器
*/
public void install() {
Thread.setDefaultUncaughtExceptionHandler(this);
Log.i(TAG, "全局异常处理器已安装,自动重启: " + enableAutoRestart);
}
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
try {
Log.e(TAG, "捕获到未处理异常", throwable);
// 保存异常信息到文件
saveExceptionToFile(throwable, thread);
// 记录系统状态
recordSystemState();
// 如果启用自动重启尝试重启应用
if (enableAutoRestart) {
restartApplication();
}
} catch (Exception e) {
Log.e(TAG, "处理异常时发生错误", e);
} finally {
// 调用默认异常处理器
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, throwable);
} else {
System.exit(1);
}
}
}
/**
* 保存异常信息到文件
*/
private void saveExceptionToFile(Throwable throwable, Thread thread) {
try {
// 创建崩溃日志目录
File crashLogDir = new File(context.getFilesDir(), CRASH_LOG_DIR);
if (!crashLogDir.exists()) {
crashLogDir.mkdirs();
}
// 生成日志文件名
String timestamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault()).format(new Date());
String fileName = CRASH_LOG_PREFIX + timestamp + ".log";
File crashLogFile = new File(crashLogDir, fileName);
// 写入异常信息
FileWriter fileWriter = new FileWriter(crashLogFile);
PrintWriter printWriter = new PrintWriter(fileWriter);
// 写入基本信息
printWriter.println("=== 应用崩溃日志 ===");
printWriter.println("时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date()));
printWriter.println("线程: " + thread.getName() + " (ID: " + thread.getId() + ")");
printWriter.println("应用包名: " + context.getPackageName());
printWriter.println();
// 写入设备信息
printWriter.println("=== 设备信息 ===");
printWriter.println("设备型号: " + android.os.Build.MODEL);
printWriter.println("Android版本: " + android.os.Build.VERSION.RELEASE);
printWriter.println("API级别: " + android.os.Build.VERSION.SDK_INT);
printWriter.println("制造商: " + android.os.Build.MANUFACTURER);
printWriter.println();
// 写入内存信息
printWriter.println("=== 内存信息 ===");
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
printWriter.println("最大内存: " + (maxMemory / 1024 / 1024) + "MB");
printWriter.println("已分配内存: " + (totalMemory / 1024 / 1024) + "MB");
printWriter.println("空闲内存: " + (freeMemory / 1024 / 1024) + "MB");
printWriter.println("已使用内存: " + (usedMemory / 1024 / 1024) + "MB");
printWriter.println("内存使用率: " + String.format("%.1f%%", (float) usedMemory / maxMemory * 100));
printWriter.println();
// 写入异常堆栈
printWriter.println("=== 异常堆栈 ===");
throwable.printStackTrace(printWriter);
printWriter.close();
fileWriter.close();
Log.i(TAG, "崩溃日志已保存: " + crashLogFile.getAbsolutePath());
// 清理旧的日志文件
cleanupOldCrashLogs(crashLogDir);
} catch (IOException e) {
Log.e(TAG, "保存崩溃日志失败", e);
}
}
/**
* 记录系统状态
*/
private void recordSystemState() {
try {
Log.i(TAG, "=== 崩溃时系统状态 ===");
// 记录内存使用情况
MemoryManager memoryManager = MemoryManager.getInstance(context);
float memoryUsage = memoryManager.getCurrentMemoryUsage();
Log.i(TAG, "内存使用率: " + String.format("%.1f%%", memoryUsage * 100));
// 记录网络状态
NetworkStabilityManager networkManager = NetworkStabilityManager.getInstance(context);
boolean networkAvailable = networkManager.isNetworkAvailable();
String networkType = networkManager.getNetworkTypeDescription();
Log.i(TAG, "网络状态: " + (networkAvailable ? "可用" : "不可用") + " (" + networkType + ")");
// 记录线程信息
Thread currentThread = Thread.currentThread();
ThreadGroup threadGroup = currentThread.getThreadGroup();
if (threadGroup != null) {
Log.i(TAG, "活跃线程数: " + threadGroup.activeCount());
}
Log.i(TAG, "========================");
} catch (Exception e) {
Log.e(TAG, "记录系统状态失败", e);
}
}
/**
* 重启应用程序
*/
private void restartApplication() {
try {
Log.w(TAG, "准备重启应用程序...");
// 创建重启Intent
Intent restartIntent = new Intent(context, MainActivity.class);
restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// 使用AlarmManager延迟重启确保当前进程完全结束
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
restartIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + RESTART_DELAY,
pendingIntent
);
Log.i(TAG, "应用程序将在 " + RESTART_DELAY + "ms 后重启");
} else {
// 如果AlarmManager不可用直接启动
context.startActivity(restartIntent);
}
// 退出当前进程
System.exit(0);
} catch (Exception e) {
Log.e(TAG, "重启应用程序失败", e);
// 强制退出
System.exit(1);
}
}
/**
* 清理旧的崩溃日志文件
*/
private void cleanupOldCrashLogs(File crashLogDir) {
try {
File[] logFiles = crashLogDir.listFiles();
if (logFiles == null || logFiles.length <= MAX_CRASH_LOGS) {
return;
}
// 按修改时间排序
java.util.Arrays.sort(logFiles, new java.util.Comparator<File>() {
@Override
public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
}
});
// 删除最旧的文件
int filesToDelete = logFiles.length - MAX_CRASH_LOGS;
for (int i = 0; i < filesToDelete; i++) {
if (logFiles[i].delete()) {
Log.d(TAG, "已删除旧的崩溃日志: " + logFiles[i].getName());
}
}
} catch (Exception e) {
Log.e(TAG, "清理崩溃日志失败", e);
}
}
/**
* 设置是否启用自动重启
*/
public void setAutoRestartEnabled(boolean enabled) {
this.enableAutoRestart = enabled;
Log.i(TAG, "自动重启设置: " + enabled);
}
/**
* 获取崩溃日志目录
*/
public File getCrashLogDirectory() {
return new File(context.getFilesDir(), CRASH_LOG_DIR);
}
/**
* 获取最新的崩溃日志文件
*/
public File getLatestCrashLog() {
File crashLogDir = getCrashLogDirectory();
if (!crashLogDir.exists()) {
return null;
}
File[] logFiles = crashLogDir.listFiles();
if (logFiles == null || logFiles.length == 0) {
return null;
}
// 找到最新的文件
File latestFile = logFiles[0];
for (File file : logFiles) {
if (file.lastModified() > latestFile.lastModified()) {
latestFile = file;
}
}
return latestFile;
}
}

406
app/src/main/java/com/ouxuan/oxface/utils/HealthMonitor.java

@ -0,0 +1,406 @@
package com.ouxuan.oxface.utils;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.ouxuan.oxface.network.NetworkStabilityManager;
import com.ouxuan.oxface.utils.UtilCodeHelper;
/**
* 健康监控器
* 用于24小时无人值守环境下的系统健康状态监控
*/
public class HealthMonitor {
private static final String TAG = "HealthMonitor";
private static final long HEALTH_CHECK_INTERVAL = 60 * 1000; // 1分钟检查间隔
private static final long CRITICAL_CHECK_INTERVAL = 10 * 1000; // 10秒紧急检查间隔
private static final int MAX_CONSECUTIVE_FAILURES = 3; // 最大连续失败次数
private static HealthMonitor instance;
private Context context;
private Handler healthHandler;
private boolean isMonitoring = false;
private HealthStatusListener healthStatusListener;
// 健康状态计数器
private int consecutiveMemoryFailures = 0;
private int consecutiveNetworkFailures = 0;
private long lastHealthCheckTime = 0;
private boolean isSystemHealthy = true;
public interface HealthStatusListener {
void onHealthStatusChanged(HealthStatus status);
void onCriticalIssueDetected(String issue);
void onSystemRecovered(String recoveryAction);
}
public enum HealthStatus {
HEALTHY, // 健康
WARNING, // 警告
CRITICAL, // 严重
SYSTEM_ERROR // 系统错误
}
public static class HealthReport {
public HealthStatus overallStatus;
public float memoryUsage;
public boolean networkAvailable;
public String networkType;
public boolean keepAliveActive;
public long uptime;
public int memoryFailures;
public int networkFailures;
public String lastIssue;
public String recommendations;
}
private HealthMonitor(Context context) {
this.context = context.getApplicationContext();
this.healthHandler = new Handler(Looper.getMainLooper());
}
public static synchronized HealthMonitor getInstance(Context context) {
if (instance == null) {
instance = new HealthMonitor(context);
}
return instance;
}
/**
* 开始健康检查
*/
public void startHealthCheck(HealthStatusListener listener) {
if (isMonitoring) {
Log.i(TAG, "健康监控已在运行中");
return;
}
this.healthStatusListener = listener;
isMonitoring = true;
Log.i(TAG, "健康监控已启动");
LogManager.logOperation("HealthMonitor", "健康监控启动");
// 启动定期健康检查
scheduleHealthCheck();
}
/**
* 停止健康检查
*/
public void stopHealthCheck() {
if (!isMonitoring) {
return;
}
isMonitoring = false;
if (healthHandler != null) {
healthHandler.removeCallbacksAndMessages(null);
}
Log.i(TAG, "健康监控已停止");
LogManager.logOperation("HealthMonitor", "健康监控停止");
}
/**
* 调度健康检查
*/
private void scheduleHealthCheck() {
if (!isMonitoring) {
return;
}
long interval = isSystemHealthy ? HEALTH_CHECK_INTERVAL : CRITICAL_CHECK_INTERVAL;
healthHandler.postDelayed(new Runnable() {
@Override
public void run() {
performHealthCheck();
scheduleHealthCheck();
}
}, interval);
}
/**
* 执行健康检查
*/
public void performHealthCheck() {
try {
lastHealthCheckTime = System.currentTimeMillis();
Log.d(TAG, "开始健康检查");
HealthReport report = generateHealthReport();
// 分析健康状态
HealthStatus currentStatus = analyzeHealthStatus(report);
// 处理健康状态变化
handleHealthStatusChange(currentStatus, report);
// 记录健康检查结果
logHealthCheckResult(report);
Log.d(TAG, "健康检查完成,状态: " + currentStatus);
} catch (Exception e) {
Log.e(TAG, "健康检查失败", e);
LogManager.logError(TAG, "健康检查失败", e);
}
}
/**
* 生成健康报告
*/
private HealthReport generateHealthReport() {
HealthReport report = new HealthReport();
try {
// 检查内存状态
MemoryManager memoryManager = MemoryManager.getInstance(context);
report.memoryUsage = memoryManager.getCurrentMemoryUsage();
// 检查网络状态
NetworkStabilityManager networkManager = NetworkStabilityManager.getInstance(context);
report.networkAvailable = networkManager.isNetworkAvailable();
report.networkType = networkManager.getNetworkTypeDescription();
// 检查保持活跃状态
KeepAliveManager keepAliveManager = KeepAliveManager.getInstance(context);
report.keepAliveActive = keepAliveManager.isKeepingAlive();
// 计算运行时间
report.uptime = System.currentTimeMillis() - getAppStartTime();
// 记录失败次数
report.memoryFailures = consecutiveMemoryFailures;
report.networkFailures = consecutiveNetworkFailures;
} catch (Exception e) {
Log.e(TAG, "生成健康报告失败", e);
report.lastIssue = "生成健康报告失败: " + e.getMessage();
}
return report;
}
/**
* 分析健康状态
*/
private HealthStatus analyzeHealthStatus(HealthReport report) {
HealthStatus status = HealthStatus.HEALTHY;
// 检查内存使用率
if (report.memoryUsage > 0.95f) {
status = HealthStatus.CRITICAL;
consecutiveMemoryFailures++;
report.lastIssue = "内存使用率过高: " + String.format("%.1f%%", report.memoryUsage * 100);
} else if (report.memoryUsage > 0.85f) {
status = HealthStatus.WARNING;
consecutiveMemoryFailures++;
report.lastIssue = "内存使用率警告: " + String.format("%.1f%%", report.memoryUsage * 100);
} else {
consecutiveMemoryFailures = 0;
}
// 检查网络状态
if (!report.networkAvailable) {
if (status == HealthStatus.HEALTHY) {
status = HealthStatus.WARNING;
} else if (status == HealthStatus.WARNING) {
status = HealthStatus.CRITICAL;
}
consecutiveNetworkFailures++;
report.lastIssue = "网络连接不可用";
} else {
consecutiveNetworkFailures = 0;
}
// 检查连续失败次数
if (consecutiveMemoryFailures > MAX_CONSECUTIVE_FAILURES ||
consecutiveNetworkFailures > MAX_CONSECUTIVE_FAILURES) {
status = HealthStatus.SYSTEM_ERROR;
report.lastIssue = "系统连续失败次数过多";
}
// 检查保持活跃状态
if (!report.keepAliveActive && status == HealthStatus.HEALTHY) {
status = HealthStatus.WARNING;
report.lastIssue = "应用保持活跃功能未启用";
}
report.overallStatus = status;
// 生成建议
generateRecommendations(report);
return status;
}
/**
* 生成建议
*/
private void generateRecommendations(HealthReport report) {
StringBuilder recommendations = new StringBuilder();
if (report.memoryUsage > 0.85f) {
recommendations.append("建议清理内存缓存; ");
}
if (!report.networkAvailable) {
recommendations.append("检查网络连接; ");
}
if (!report.keepAliveActive) {
recommendations.append("启用应用保持活跃功能; ");
}
if (report.memoryFailures > 0 || report.networkFailures > 0) {
recommendations.append("监控系统稳定性; ");
}
if (recommendations.length() == 0) {
recommendations.append("系统运行正常");
}
report.recommendations = recommendations.toString();
}
/**
* 处理健康状态变化
*/
private void handleHealthStatusChange(HealthStatus currentStatus, HealthReport report) {
boolean statusChanged = (isSystemHealthy && currentStatus != HealthStatus.HEALTHY) ||
(!isSystemHealthy && currentStatus == HealthStatus.HEALTHY);
if (statusChanged) {
isSystemHealthy = (currentStatus == HealthStatus.HEALTHY);
if (healthStatusListener != null) {
healthStatusListener.onHealthStatusChanged(currentStatus);
}
LogManager.logOperation("HealthMonitor",
"健康状态变化: " + currentStatus + ", " + report.lastIssue);
}
// 处理严重问题
if (currentStatus == HealthStatus.CRITICAL || currentStatus == HealthStatus.SYSTEM_ERROR) {
handleCriticalIssue(report);
}
// 处理系统恢复
if (isSystemHealthy && (consecutiveMemoryFailures == 0 && consecutiveNetworkFailures == 0)) {
handleSystemRecovery();
}
}
/**
* 处理严重问题
*/
private void handleCriticalIssue(HealthReport report) {
Log.w(TAG, "检测到严重问题: " + report.lastIssue);
if (healthStatusListener != null) {
healthStatusListener.onCriticalIssueDetected(report.lastIssue);
}
// 尝试自动恢复
attemptAutoRecovery(report);
}
/**
* 尝试自动恢复
*/
private void attemptAutoRecovery(HealthReport report) {
try {
Log.i(TAG, "尝试自动恢复: " + report.overallStatus);
if (report.memoryUsage > 0.90f) {
// 执行内存清理
MemoryManager memoryManager = MemoryManager.getInstance(context);
memoryManager.performMemoryCleanup();
LogManager.logOperation("HealthMonitor", "自动执行内存清理");
}
if (!report.networkAvailable) {
// 网络问题通常需要等待恢复记录日志
LogManager.logWarning(TAG, "网络不可用,等待网络恢复");
}
if (!report.keepAliveActive) {
// 记录保持活跃状态问题
LogManager.logWarning(TAG, "保持活跃功能未启用");
}
} catch (Exception e) {
Log.e(TAG, "自动恢复失败", e);
LogManager.logError(TAG, "自动恢复失败", e);
}
}
/**
* 处理系统恢复
*/
private void handleSystemRecovery() {
if (healthStatusListener != null) {
healthStatusListener.onSystemRecovered("系统已恢复正常运行");
}
LogManager.logOperation("HealthMonitor", "系统已恢复正常运行");
}
/**
* 记录健康检查结果
*/
private void logHealthCheckResult(HealthReport report) {
String message = String.format(
"健康检查 - 状态:%s, 内存:%.1f%%, 网络:%s, 保活:%s, 运行时间:%dh",
report.overallStatus,
report.memoryUsage * 100,
report.networkAvailable ? "正常" : "异常",
report.keepAliveActive ? "是" : "否",
report.uptime / (1000 * 60 * 60)
);
if (report.overallStatus == HealthStatus.HEALTHY) {
LogManager.logDebug(TAG, message);
} else {
LogManager.logWarning(TAG, message + " - " + report.lastIssue);
}
}
/**
* 获取应用启动时间简化实现
*/
private long getAppStartTime() {
// 这里可以在Application中记录实际的启动时间
// 现在使用一个简化的实现
return System.currentTimeMillis() - (24 * 60 * 60 * 1000); // 假设已运行24小时
}
/**
* 获取当前健康报告
*/
public HealthReport getCurrentHealthReport() {
return generateHealthReport();
}
/**
* 检查系统是否健康
*/
public boolean isSystemHealthy() {
return isSystemHealthy;
}
/**
* 获取上次健康检查时间
*/
public long getLastHealthCheckTime() {
return lastHealthCheckTime;
}
}

241
app/src/main/java/com/ouxuan/oxface/utils/KeepAliveManager.java

@ -0,0 +1,241 @@
package com.ouxuan.oxface.utils;
import android.app.Activity;
import android.content.Context;
import android.os.PowerManager;
import android.util.Log;
import android.view.WindowManager;
/**
* 保持活跃管理器
* 用于24小时无人值守环境下保持应用活跃状态
*/
public class KeepAliveManager {
private static final String TAG = "KeepAliveManager";
private static final String WAKE_LOCK_TAG = "OxFace:KeepAlive";
private static KeepAliveManager instance;
private Context context;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private boolean isKeepingAlive = false;
private KeepAliveManager(Context context) {
this.context = context.getApplicationContext();
this.powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
}
public static synchronized KeepAliveManager getInstance(Context context) {
if (instance == null) {
instance = new KeepAliveManager(context);
}
return instance;
}
/**
* 开始保持应用活跃
*/
public void startKeepAlive(Activity activity) {
if (isKeepingAlive) {
Log.i(TAG, "应用已处于保持活跃状态");
return;
}
try {
// 保持屏幕常亮
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.i(TAG, "已设置屏幕常亮");
}
});
}
// 获取部分唤醒锁
if (powerManager != null) {
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
WAKE_LOCK_TAG
);
wakeLock.acquire();
Log.i(TAG, "已获取唤醒锁");
}
isKeepingAlive = true;
Log.i(TAG, "应用保持活跃已启动");
// 记录到日志
LogManager.logOperation("KeepAlive", "应用保持活跃功能已启动");
} catch (Exception e) {
Log.e(TAG, "启动保持活跃失败", e);
LogManager.logError(TAG, "启动保持活跃失败", e);
}
}
/**
* 停止保持应用活跃
*/
public void stopKeepAlive(Activity activity) {
if (!isKeepingAlive) {
Log.i(TAG, "应用未处于保持活跃状态");
return;
}
try {
// 清除屏幕常亮标志
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.i(TAG, "已清除屏幕常亮设置");
}
});
}
// 释放唤醒锁
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
wakeLock = null;
Log.i(TAG, "已释放唤醒锁");
}
isKeepingAlive = false;
Log.i(TAG, "应用保持活跃已停止");
// 记录到日志
LogManager.logOperation("KeepAlive", "应用保持活跃功能已停止");
} catch (Exception e) {
Log.e(TAG, "停止保持活跃失败", e);
LogManager.logError(TAG, "停止保持活跃失败", e);
}
}
/**
* 检查是否正在保持活跃
*/
public boolean isKeepingAlive() {
return isKeepingAlive;
}
/**
* 检查唤醒锁状态
*/
public boolean isWakeLockHeld() {
return wakeLock != null && wakeLock.isHeld();
}
/**
* 检查屏幕是否保持开启
*/
public boolean isScreenOn() {
if (powerManager != null) {
return powerManager.isInteractive();
}
return false;
}
/**
* 获取电源管理信息
*/
public String getPowerInfo() {
StringBuilder info = new StringBuilder();
try {
if (powerManager != null) {
info.append("屏幕状态: ").append(isScreenOn() ? "开启" : "关闭").append("\n");
info.append("唤醒锁状态: ").append(isWakeLockHeld() ? "持有" : "未持有").append("\n");
info.append("保持活跃状态: ").append(isKeepingAlive ? "是" : "否").append("\n");
// 检查是否处于省电模式
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
boolean isPowerSaveMode = powerManager.isPowerSaveMode();
info.append("省电模式: ").append(isPowerSaveMode ? "开启" : "关闭").append("\n");
}
// 检查是否忽略电池优化
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
boolean isIgnoringBatteryOptimizations =
powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
info.append("忽略电池优化: ").append(isIgnoringBatteryOptimizations ? "是" : "否").append("\n");
}
}
} catch (Exception e) {
Log.e(TAG, "获取电源信息失败", e);
info.append("获取电源信息失败: ").append(e.getMessage());
}
return info.toString();
}
/**
* 请求忽略电池优化需要用户手动操作
*/
public boolean requestIgnoreBatteryOptimizations(Activity activity) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
try {
if (powerManager != null &&
!powerManager.isIgnoringBatteryOptimizations(context.getPackageName())) {
android.content.Intent intent = new android.content.Intent();
intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(android.net.Uri.parse("package:" + context.getPackageName()));
if (intent.resolveActivity(context.getPackageManager()) != null) {
activity.startActivity(intent);
Log.i(TAG, "已请求忽略电池优化");
LogManager.logOperation("KeepAlive", "请求忽略电池优化");
return true;
}
}
} catch (Exception e) {
Log.e(TAG, "请求忽略电池优化失败", e);
LogManager.logError(TAG, "请求忽略电池优化失败", e);
}
}
return false;
}
/**
* 强制保持屏幕开启用于关键操作期间
*/
public void forceKeepScreenOn(Activity activity, long durationMillis) {
if (activity == null) {
return;
}
Log.i(TAG, "强制保持屏幕开启 " + durationMillis + "ms");
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// 延时后清除标志
activity.getWindow().getDecorView().postDelayed(new Runnable() {
@Override
public void run() {
if (!isKeepingAlive) { // 如果没有全局保持活跃才清除标志
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.i(TAG, "临时屏幕保持已结束");
}
}
}, durationMillis);
}
});
}
/**
* 记录电源状态到日志
*/
public void logPowerStatus() {
String powerInfo = getPowerInfo();
Log.i(TAG, "电源状态:\n" + powerInfo);
LogManager.logInfo(TAG, "电源状态: " + powerInfo.replace("\n", ", "));
}
}

375
app/src/main/java/com/ouxuan/oxface/utils/LogManager.java

@ -0,0 +1,375 @@
package com.ouxuan.oxface.utils;
import android.content.Context;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 日志管理器
* 用于24小时无人值守环境下的日志记录和管理
*/
public class LogManager {
private static final String TAG = "LogManager";
private static final String LOG_DIR = "operation_logs";
private static final String LOG_FILE_NAME = "oxface_operation.log";
private static final long MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
private static final int MAX_LOG_FILES = 5; // 最多保留5个日志文件
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
private static LogManager instance;
private Context context;
private File logDir;
private File currentLogFile;
private BlockingQueue<LogEntry> logQueue;
private Thread logWriterThread;
private volatile boolean isRunning = false;
private SimpleDateFormat dateFormat;
private static class LogEntry {
final long timestamp;
final String level;
final String tag;
final String message;
final Throwable throwable;
LogEntry(String level, String tag, String message, Throwable throwable) {
this.timestamp = System.currentTimeMillis();
this.level = level;
this.tag = tag;
this.message = message;
this.throwable = throwable;
}
}
private LogManager(Context context) {
this.context = context.getApplicationContext();
this.dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());
this.logQueue = new LinkedBlockingQueue<>();
// 创建日志目录
this.logDir = new File(context.getFilesDir(), LOG_DIR);
if (!logDir.exists()) {
logDir.mkdirs();
}
// 设置当前日志文件
this.currentLogFile = new File(logDir, LOG_FILE_NAME);
}
public static synchronized LogManager getInstance(Context context) {
if (instance == null) {
instance = new LogManager(context);
}
return instance;
}
/**
* 启动日志管理器
*/
public void start() {
if (isRunning) {
return;
}
isRunning = true;
logWriterThread = new Thread(new Runnable() {
@Override
public void run() {
runLogWriter();
}
});
logWriterThread.setName("LogWriter");
logWriterThread.setDaemon(true);
logWriterThread.start();
Log.i(TAG, "日志管理器已启动");
logInfo(TAG, "日志管理器启动");
}
/**
* 停止日志管理器
*/
public void stop() {
if (!isRunning) {
return;
}
isRunning = false;
if (logWriterThread != null) {
logWriterThread.interrupt();
try {
logWriterThread.join(5000); // 等待最多5秒
} catch (InterruptedException e) {
Log.w(TAG, "等待日志写入线程结束被中断");
}
}
// 处理队列中剩余的日志
processRemainingLogs();
Log.i(TAG, "日志管理器已停止");
}
/**
* 记录调试日志
*/
public static void logDebug(String tag, String message) {
if (instance != null) {
instance.addLogEntry("DEBUG", tag, message, null);
}
}
/**
* 记录信息日志
*/
public static void logInfo(String tag, String message) {
if (instance != null) {
instance.addLogEntry("INFO", tag, message, null);
}
}
/**
* 记录警告日志
*/
public static void logWarning(String tag, String message) {
if (instance != null) {
instance.addLogEntry("WARN", tag, message, null);
}
}
/**
* 记录错误日志
*/
public static void logError(String tag, String message) {
if (instance != null) {
instance.addLogEntry("ERROR", tag, message, null);
}
}
/**
* 记录错误日志带异常
*/
public static void logError(String tag, String message, Throwable throwable) {
if (instance != null) {
instance.addLogEntry("ERROR", tag, message, throwable);
}
}
/**
* 记录操作日志
*/
public static void logOperation(String operation, String details) {
if (instance != null) {
instance.addLogEntry("OPERATION", "App", operation + ": " + details, null);
}
}
/**
* 记录性能日志
*/
public static void logPerformance(String operation, long duration) {
if (instance != null) {
String message = String.format("%s 耗时: %dms", operation, duration);
instance.addLogEntry("PERFORMANCE", "App", message, null);
}
}
/**
* 添加日志条目到队列
*/
private void addLogEntry(String level, String tag, String message, Throwable throwable) {
try {
LogEntry entry = new LogEntry(level, tag, message, throwable);
if (!logQueue.offer(entry)) {
Log.w(TAG, "日志队列已满,丢弃日志: " + message);
}
} catch (Exception e) {
Log.e(TAG, "添加日志条目失败", e);
}
}
/**
* 运行日志写入器
*/
private void runLogWriter() {
BufferedWriter writer = null;
try {
while (isRunning || !logQueue.isEmpty()) {
try {
LogEntry entry = logQueue.take(); // 阻塞等待日志条目
// 检查是否需要轮转日志文件
checkLogRotation();
// 打开或重新打开文件
if (writer == null) {
writer = new BufferedWriter(new FileWriter(currentLogFile, true));
}
// 写入日志
writeLogEntry(writer, entry);
// 定期刷新缓冲区
writer.flush();
} catch (InterruptedException e) {
if (!isRunning) {
break;
}
} catch (IOException e) {
Log.e(TAG, "写入日志失败", e);
// 重新打开文件
if (writer != null) {
try {
writer.close();
} catch (IOException ignored) {
}
writer = null;
}
}
}
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
Log.e(TAG, "关闭日志文件失败", e);
}
}
}
}
/**
* 写入日志条目
*/
private void writeLogEntry(BufferedWriter writer, LogEntry entry) throws IOException {
String timestamp = dateFormat.format(new Date(entry.timestamp));
String logLine = String.format("[%s] %s/%s: %s%n",
timestamp, entry.level, entry.tag, entry.message);
writer.write(logLine);
// 如果有异常写入堆栈信息
if (entry.throwable != null) {
writer.write("Exception: " + entry.throwable.toString() + "\n");
StackTraceElement[] stackTrace = entry.throwable.getStackTrace();
for (StackTraceElement element : stackTrace) {
writer.write(" at " + element.toString() + "\n");
}
}
}
/**
* 检查日志轮转
*/
private void checkLogRotation() {
if (currentLogFile.exists() && currentLogFile.length() > MAX_LOG_SIZE) {
rotateLogFile();
}
}
/**
* 轮转日志文件
*/
private void rotateLogFile() {
try {
String timestamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault()).format(new Date());
String rotatedFileName = "oxface_operation_" + timestamp + ".log";
File rotatedFile = new File(logDir, rotatedFileName);
if (currentLogFile.renameTo(rotatedFile)) {
Log.i(TAG, "日志文件轮转成功: " + rotatedFileName);
// 清理旧的日志文件
cleanupOldLogFiles();
} else {
Log.w(TAG, "日志文件轮转失败");
}
} catch (Exception e) {
Log.e(TAG, "日志轮转失败", e);
}
}
/**
* 清理旧的日志文件
*/
private void cleanupOldLogFiles() {
try {
File[] logFiles = logDir.listFiles();
if (logFiles == null || logFiles.length <= MAX_LOG_FILES) {
return;
}
// 按修改时间排序
java.util.Arrays.sort(logFiles, new java.util.Comparator<File>() {
@Override
public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
}
});
// 删除最旧的文件保留当前日志文件
int filesToDelete = logFiles.length - MAX_LOG_FILES;
for (int i = 0; i < filesToDelete; i++) {
if (!logFiles[i].equals(currentLogFile) && logFiles[i].delete()) {
Log.d(TAG, "已删除旧日志文件: " + logFiles[i].getName());
}
}
} catch (Exception e) {
Log.e(TAG, "清理旧日志文件失败", e);
}
}
/**
* 处理队列中剩余的日志
*/
private void processRemainingLogs() {
if (logQueue.isEmpty()) {
return;
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(currentLogFile, true))) {
LogEntry entry;
while ((entry = logQueue.poll()) != null) {
writeLogEntry(writer, entry);
}
writer.flush();
} catch (IOException e) {
Log.e(TAG, "处理剩余日志失败", e);
}
}
/**
* 获取日志目录
*/
public File getLogDirectory() {
return logDir;
}
/**
* 获取当前日志文件
*/
public File getCurrentLogFile() {
return currentLogFile;
}
/**
* 获取日志文件大小
*/
public long getLogFileSize() {
return currentLogFile.exists() ? currentLogFile.length() : 0;
}
}

533
app/src/main/java/com/ouxuan/oxface/utils/MaintenanceScheduler.java

@ -0,0 +1,533 @@
package com.ouxuan.oxface.utils;
import android.content.Context;
import android.util.Log;
import com.bumptech.glide.Glide;
import com.ouxuan.oxface.network.NetworkManager;
import com.ouxuan.oxface.network.NetworkStabilityManager;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 维护任务调度器
* 用于24小时无人值守环境下的定时维护任务
*/
public class MaintenanceScheduler {
private static final String TAG = "MaintenanceScheduler";
// 维护间隔时间毫秒
private static final long LIGHT_MAINTENANCE_INTERVAL = 30 * 60 * 1000; // 30分钟 - 轻度维护
private static final long MEDIUM_MAINTENANCE_INTERVAL = 2 * 60 * 60 * 1000; // 2小时 - 中度维护
private static final long HEAVY_MAINTENANCE_INTERVAL = 6 * 60 * 60 * 1000; // 6小时 - 重度维护
private static final long DAILY_MAINTENANCE_INTERVAL = 24 * 60 * 60 * 1000; // 24小时 - 每日维护
private static MaintenanceScheduler instance;
private Context context;
private ScheduledExecutorService scheduledExecutor;
private boolean isRunning = false;
// 维护任务计数器
private int lightMaintenanceCount = 0;
private int mediumMaintenanceCount = 0;
private int heavyMaintenanceCount = 0;
private int dailyMaintenanceCount = 0;
private MaintenanceScheduler(Context context) {
this.context = context.getApplicationContext();
this.scheduledExecutor = Executors.newScheduledThreadPool(2);
}
public static synchronized MaintenanceScheduler getInstance(Context context) {
if (instance == null) {
instance = new MaintenanceScheduler(context);
}
return instance;
}
/**
* 启动维护任务调度
*/
public void startMaintenance() {
if (isRunning) {
Log.i(TAG, "维护调度器已在运行中");
return;
}
isRunning = true;
// 调度轻度维护任务 - 每30分钟
scheduledExecutor.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
performLightMaintenance();
}
},
LIGHT_MAINTENANCE_INTERVAL,
LIGHT_MAINTENANCE_INTERVAL,
TimeUnit.MILLISECONDS
);
// 调度中度维护任务 - 每2小时
scheduledExecutor.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
performMediumMaintenance();
}
},
MEDIUM_MAINTENANCE_INTERVAL,
MEDIUM_MAINTENANCE_INTERVAL,
TimeUnit.MILLISECONDS
);
// 调度重度维护任务 - 每6小时
scheduledExecutor.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
performHeavyMaintenance();
}
},
HEAVY_MAINTENANCE_INTERVAL,
HEAVY_MAINTENANCE_INTERVAL,
TimeUnit.MILLISECONDS
);
// 调度每日维护任务 - 每24小时
scheduledExecutor.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
performDailyMaintenance();
}
},
DAILY_MAINTENANCE_INTERVAL,
DAILY_MAINTENANCE_INTERVAL,
TimeUnit.MILLISECONDS
);
Log.i(TAG, "维护任务调度器已启动");
LogManager.logOperation("MaintenanceScheduler", "维护任务调度器启动");
}
/**
* 停止维护任务调度
*/
public void stopMaintenance() {
if (!isRunning) {
return;
}
isRunning = false;
if (scheduledExecutor != null && !scheduledExecutor.isShutdown()) {
scheduledExecutor.shutdown();
try {
if (!scheduledExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
scheduledExecutor.shutdownNow();
}
} catch (InterruptedException e) {
scheduledExecutor.shutdownNow();
Thread.currentThread().interrupt();
}
}
Log.i(TAG, "维护任务调度器已停止");
LogManager.logOperation("MaintenanceScheduler", "维护任务调度器停止");
}
/**
* 轻度维护任务 - 每30分钟执行
*/
private void performLightMaintenance() {
try {
lightMaintenanceCount++;
Log.d(TAG, "开始轻度维护任务 #" + lightMaintenanceCount);
long startTime = System.currentTimeMillis();
// 检查内存状态
checkMemoryStatus();
// 检查网络状态
checkNetworkStatus();
// 轻量级垃圾回收建议
System.gc();
long duration = System.currentTimeMillis() - startTime;
Log.d(TAG, "轻度维护任务完成,耗时: " + duration + "ms");
LogManager.logPerformance("轻度维护任务", duration);
} catch (Exception e) {
Log.e(TAG, "轻度维护任务失败", e);
LogManager.logError(TAG, "轻度维护任务失败", e);
}
}
/**
* 中度维护任务 - 每2小时执行
*/
private void performMediumMaintenance() {
try {
mediumMaintenanceCount++;
Log.i(TAG, "开始中度维护任务 #" + mediumMaintenanceCount);
long startTime = System.currentTimeMillis();
// 执行内存清理
performMemoryCleanup();
// 检查应用保持活跃状态
checkKeepAliveStatus();
// 执行网络连接重置
resetNetworkConnections();
// 更强力的垃圾回收
for (int i = 0; i < 3; i++) {
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
long duration = System.currentTimeMillis() - startTime;
Log.i(TAG, "中度维护任务完成,耗时: " + duration + "ms");
LogManager.logPerformance("中度维护任务", duration);
} catch (Exception e) {
Log.e(TAG, "中度维护任务失败", e);
LogManager.logError(TAG, "中度维护任务失败", e);
}
}
/**
* 重度维护任务 - 每6小时执行
*/
private void performHeavyMaintenance() {
try {
heavyMaintenanceCount++;
Log.w(TAG, "开始重度维护任务 #" + heavyMaintenanceCount);
long startTime = System.currentTimeMillis();
// 执行深度内存清理
performDeepMemoryCleanup();
// 清理磁盘缓存
clearDiskCaches();
// 重新初始化网络管理器
reinitializeNetworkManager();
// 执行健康检查
performSystemHealthCheck();
// 清理日志文件
cleanupLogFiles();
long duration = System.currentTimeMillis() - startTime;
Log.w(TAG, "重度维护任务完成,耗时: " + duration + "ms");
LogManager.logPerformance("重度维护任务", duration);
} catch (Exception e) {
Log.e(TAG, "重度维护任务失败", e);
LogManager.logError(TAG, "重度维护任务失败", e);
}
}
/**
* 每日维护任务 - 每24小时执行
*/
private void performDailyMaintenance() {
try {
dailyMaintenanceCount++;
Log.w(TAG, "开始每日维护任务 #" + dailyMaintenanceCount);
long startTime = System.currentTimeMillis();
// 生成系统运行报告
generateSystemReport();
// 执行全面系统清理
performComprehensiveCleanup();
// 重置所有计数器和统计数据
resetCounters();
// 验证系统完整性
validateSystemIntegrity();
long duration = System.currentTimeMillis() - startTime;
Log.w(TAG, "每日维护任务完成,耗时: " + duration + "ms");
LogManager.logPerformance("每日维护任务", duration);
LogManager.logOperation("MaintenanceScheduler", "完成第" + dailyMaintenanceCount + "次每日维护");
} catch (Exception e) {
Log.e(TAG, "每日维护任务失败", e);
LogManager.logError(TAG, "每日维护任务失败", e);
}
}
/**
* 检查内存状态
*/
private void checkMemoryStatus() {
MemoryManager memoryManager = MemoryManager.getInstance(context);
float memoryUsage = memoryManager.getCurrentMemoryUsage();
if (memoryUsage > 0.80f) {
Log.w(TAG, "内存使用率较高: " + String.format("%.1f%%", memoryUsage * 100));
memoryManager.performMemoryCleanup();
}
}
/**
* 检查网络状态
*/
private void checkNetworkStatus() {
NetworkStabilityManager networkManager = NetworkStabilityManager.getInstance(context);
boolean networkAvailable = networkManager.isNetworkAvailable();
if (!networkAvailable) {
Log.w(TAG, "网络连接不可用");
LogManager.logWarning(TAG, "维护检查发现网络连接不可用");
}
}
/**
* 执行内存清理
*/
private void performMemoryCleanup() {
MemoryManager memoryManager = MemoryManager.getInstance(context);
memoryManager.performMemoryCleanup();
// 清理Glide缓存
Glide.get(context).clearMemory();
Log.d(TAG, "内存清理完成");
}
/**
* 检查保持活跃状态
*/
private void checkKeepAliveStatus() {
KeepAliveManager keepAliveManager = KeepAliveManager.getInstance(context);
boolean isKeepingAlive = keepAliveManager.isKeepingAlive();
if (!isKeepingAlive) {
Log.w(TAG, "保持活跃功能未启用");
LogManager.logWarning(TAG, "维护检查发现保持活跃功能未启用");
}
// 记录电源状态
keepAliveManager.logPowerStatus();
}
/**
* 重置网络连接
*/
private void resetNetworkConnections() {
try {
// 这里可以添加重置网络连接的逻辑
// 例如重新初始化HTTP客户端等
Log.d(TAG, "网络连接重置完成");
} catch (Exception e) {
Log.e(TAG, "重置网络连接失败", e);
}
}
/**
* 执行深度内存清理
*/
private void performDeepMemoryCleanup() {
MemoryManager memoryManager = MemoryManager.getInstance(context);
// 多次执行内存清理
for (int i = 0; i < 3; i++) {
memoryManager.performMemoryCleanup();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
break;
}
}
Log.i(TAG, "深度内存清理完成");
}
/**
* 清理磁盘缓存
*/
private void clearDiskCaches() {
// 在后台线程中清理磁盘缓存
new Thread(new Runnable() {
@Override
public void run() {
try {
Glide.get(context).clearDiskCache();
Log.i(TAG, "磁盘缓存清理完成");
} catch (Exception e) {
Log.e(TAG, "磁盘缓存清理失败", e);
}
}
}).start();
}
/**
* 重新初始化网络管理器
*/
private void reinitializeNetworkManager() {
try {
NetworkManager networkManager = NetworkManager.getInstance();
// 这里可以添加重新初始化网络管理器的逻辑
Log.i(TAG, "网络管理器重新初始化完成");
} catch (Exception e) {
Log.e(TAG, "重新初始化网络管理器失败", e);
}
}
/**
* 执行系统健康检查
*/
private void performSystemHealthCheck() {
HealthMonitor healthMonitor = HealthMonitor.getInstance(context);
healthMonitor.performHealthCheck();
HealthMonitor.HealthReport report = healthMonitor.getCurrentHealthReport();
Log.i(TAG, "系统健康检查完成,状态: " + report.overallStatus);
}
/**
* 清理日志文件
*/
private void cleanupLogFiles() {
try {
// LogManager会自动处理日志轮转和清理
LogManager logManager = LogManager.getInstance(context);
Log.d(TAG, "日志文件清理检查完成");
} catch (Exception e) {
Log.e(TAG, "日志文件清理失败", e);
}
}
/**
* 生成系统运行报告
*/
private void generateSystemReport() {
try {
HealthMonitor healthMonitor = HealthMonitor.getInstance(context);
HealthMonitor.HealthReport report = healthMonitor.getCurrentHealthReport();
String reportMessage = String.format(
"系统运行报告 - 运行时间: %d小时, 内存使用: %.1f%%, 网络: %s, 维护次数: L%d/M%d/H%d/D%d",
report.uptime / (1000 * 60 * 60),
report.memoryUsage * 100,
report.networkAvailable ? "正常" : "异常",
lightMaintenanceCount,
mediumMaintenanceCount,
heavyMaintenanceCount,
dailyMaintenanceCount
);
Log.i(TAG, reportMessage);
LogManager.logOperation("SystemReport", reportMessage);
} catch (Exception e) {
Log.e(TAG, "生成系统报告失败", e);
}
}
/**
* 执行全面系统清理
*/
private void performComprehensiveCleanup() {
// 执行所有级别的清理任务
performDeepMemoryCleanup();
clearDiskCaches();
// 等待一段时间让清理任务完成
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Log.i(TAG, "全面系统清理完成");
}
/**
* 重置计数器
*/
private void resetCounters() {
lightMaintenanceCount = 0;
mediumMaintenanceCount = 0;
heavyMaintenanceCount = 0;
// 不重置每日维护计数器用于跟踪总运行天数
Log.d(TAG, "维护任务计数器已重置");
}
/**
* 验证系统完整性
*/
private void validateSystemIntegrity() {
try {
// 检查关键组件是否正常运行
boolean memoryManagerOk = MemoryManager.getInstance(context).isMemoryHealthy();
boolean networkManagerOk = NetworkStabilityManager.getInstance(context).isNetworkAvailable();
boolean keepAliveOk = KeepAliveManager.getInstance(context).isKeepingAlive();
String integrityReport = String.format(
"系统完整性检查 - 内存管理: %s, 网络管理: %s, 保持活跃: %s",
memoryManagerOk ? "正常" : "异常",
networkManagerOk ? "正常" : "异常",
keepAliveOk ? "正常" : "异常"
);
Log.i(TAG, integrityReport);
LogManager.logOperation("SystemIntegrity", integrityReport);
} catch (Exception e) {
Log.e(TAG, "系统完整性验证失败", e);
LogManager.logError(TAG, "系统完整性验证失败", e);
}
}
/**
* 获取维护统计信息
*/
public String getMaintenanceStats() {
return String.format(
"维护统计 - 轻度: %d次, 中度: %d次, 重度: %d次, 每日: %d次",
lightMaintenanceCount,
mediumMaintenanceCount,
heavyMaintenanceCount,
dailyMaintenanceCount
);
}
/**
* 立即执行维护任务
*/
public void performImmediateMaintenance() {
Log.i(TAG, "立即执行维护任务");
new Thread(new Runnable() {
@Override
public void run() {
performMediumMaintenance();
}
}).start();
}
}

245
app/src/main/java/com/ouxuan/oxface/utils/MemoryManager.java

@ -0,0 +1,245 @@
package com.ouxuan.oxface.utils;
import android.app.ActivityManager;
import android.content.Context;
import android.util.Log;
import com.bumptech.glide.Glide;
/**
* 内存管理器
* 用于24小时无人值守环境下的内存监控和优化
*/
public class MemoryManager {
private static final String TAG = "MemoryManager";
private static final float MEMORY_THRESHOLD = 0.85f; // 85%内存使用率阈值
private static final float CRITICAL_MEMORY_THRESHOLD = 0.95f; // 95%临界阈值
private static final long MEMORY_CHECK_INTERVAL = 30 * 1000; // 30秒检查间隔
private static MemoryManager instance;
private Context context;
private boolean isMonitoring = false;
private MemoryManager(Context context) {
this.context = context.getApplicationContext();
}
public static synchronized MemoryManager getInstance(Context context) {
if (instance == null) {
instance = new MemoryManager(context);
}
return instance;
}
/**
* 开始内存监控
*/
public void startMemoryMonitoring() {
if (isMonitoring) {
return;
}
isMonitoring = true;
Log.i(TAG, "开始内存监控");
Thread monitorThread = new Thread(new Runnable() {
@Override
public void run() {
while (isMonitoring) {
try {
monitorMemory();
Thread.sleep(MEMORY_CHECK_INTERVAL);
} catch (InterruptedException e) {
Log.w(TAG, "内存监控线程被中断");
break;
} catch (Exception e) {
Log.e(TAG, "内存监控异常", e);
}
}
}
});
monitorThread.setName("MemoryMonitor");
monitorThread.setDaemon(true);
monitorThread.start();
}
/**
* 停止内存监控
*/
public void stopMemoryMonitoring() {
isMonitoring = false;
Log.i(TAG, "停止内存监控");
}
/**
* 监控内存使用情况
*/
public void monitorMemory() {
try {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
float memoryUsage = (float) usedMemory / maxMemory;
// 记录详细内存信息
Log.d(TAG, String.format("内存使用情况 - 使用率: %.1f%%, 已用: %dMB, 最大: %dMB",
memoryUsage * 100, usedMemory / (1024 * 1024), maxMemory / (1024 * 1024)));
// 检查内存使用率
if (memoryUsage > CRITICAL_MEMORY_THRESHOLD) {
// 临界状态强制清理
Log.w(TAG, "内存使用率达到临界状态: " + String.format("%.1f%%", memoryUsage * 100));
performCriticalMemoryCleanup();
} else if (memoryUsage > MEMORY_THRESHOLD) {
// 超过阈值执行清理
Log.w(TAG, "内存使用率过高: " + String.format("%.1f%%", memoryUsage * 100));
performMemoryCleanup();
}
// 检查系统内存情况
checkSystemMemory();
} catch (Exception e) {
Log.e(TAG, "内存监控失败", e);
}
}
/**
* 执行内存清理
*/
public void performMemoryCleanup() {
try {
Log.i(TAG, "开始内存清理");
// 清理Glide图片缓存
if (context != null) {
Glide.get(context).clearMemory();
Log.d(TAG, "已清理Glide内存缓存");
}
// 建议垃圾回收
System.gc();
Log.d(TAG, "已触发垃圾回收");
// 记录清理后的内存状态
logMemoryStatus("清理后");
} catch (Exception e) {
Log.e(TAG, "内存清理失败", e);
}
}
/**
* 执行临界内存清理
*/
private void performCriticalMemoryCleanup() {
try {
Log.w(TAG, "执行临界内存清理");
// 清理所有可能的缓存
if (context != null) {
Glide.get(context).clearMemory();
// 强制清理磁盘缓存在后台线程中
new Thread(new Runnable() {
@Override
public void run() {
Glide.get(context).clearDiskCache();
}
}).start();
}
// 多次触发垃圾回收
for (int i = 0; i < 3; i++) {
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
Log.w(TAG, "临界内存清理完成");
} catch (Exception e) {
Log.e(TAG, "临界内存清理失败", e);
}
}
/**
* 检查系统内存情况
*/
private void checkSystemMemory() {
try {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager != null) {
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
float availableMemoryPercentage = (float) memoryInfo.availMem / memoryInfo.totalMem;
Log.d(TAG, String.format("系统内存 - 可用: %dMB, 总计: %dMB, 可用率: %.1f%%",
memoryInfo.availMem / (1024 * 1024),
memoryInfo.totalMem / (1024 * 1024),
availableMemoryPercentage * 100));
// 如果系统内存不足记录警告
if (memoryInfo.lowMemory) {
Log.w(TAG, "系统内存不足警告");
}
}
} catch (Exception e) {
Log.e(TAG, "检查系统内存失败", e);
}
}
/**
* 记录内存状态
*/
private void logMemoryStatus(String prefix) {
try {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
float memoryUsage = (float) usedMemory / maxMemory;
Log.i(TAG, String.format("%s内存状态 - 使用率: %.1f%%, 已用: %dMB, 空闲: %dMB, 最大: %dMB",
prefix,
memoryUsage * 100,
usedMemory / (1024 * 1024),
freeMemory / (1024 * 1024),
maxMemory / (1024 * 1024)));
} catch (Exception e) {
Log.e(TAG, "记录内存状态失败", e);
}
}
/**
* 获取当前内存使用率
*/
public float getCurrentMemoryUsage() {
try {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
return (float) usedMemory / maxMemory;
} catch (Exception e) {
Log.e(TAG, "获取内存使用率失败", e);
return 0f;
}
}
/**
* 检查内存是否健康
*/
public boolean isMemoryHealthy() {
return getCurrentMemoryUsage() < MEMORY_THRESHOLD;
}
}

382
app/src/main/java/com/ouxuan/oxface/utils/UtilCodeHelper.java

@ -0,0 +1,382 @@
package com.ouxuan.oxface.utils;
import android.content.Context;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.PhoneUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
/**
* UtilCode工具库使用示例类
* 提供常用的Android开发工具方法封装
*/
public class UtilCodeHelper {
private static final String TAG = "UtilCodeHelper";
/**
* 应用信息相关工具方法
*/
public static class App {
/**
* 获取应用版本名称
*/
public static String getAppVersionName() {
return AppUtils.getAppVersionName();
}
/**
* 获取应用版本号
*/
public static int getAppVersionCode() {
return AppUtils.getAppVersionCode();
}
/**
* 获取应用包名
*/
public static String getAppPackageName() {
return AppUtils.getAppPackageName();
}
/**
* 判断应用是否在前台
*/
public static boolean isAppForeground() {
return AppUtils.isAppForeground();
}
/**
* 获取应用信息摘要
*/
public static String getAppInfoSummary() {
return String.format("应用信息 - 包名: %s, 版本: %s(%d)",
getAppPackageName(), getAppVersionName(), getAppVersionCode());
}
}
/**
* 设备信息相关工具方法
*/
public static class Device {
/**
* 获取设备型号
*/
public static String getModel() {
return DeviceUtils.getModel();
}
/**
* 获取设备制造商
*/
public static String getManufacturer() {
return DeviceUtils.getManufacturer();
}
/**
* 获取Android版本
*/
public static String getSDKVersionName() {
return DeviceUtils.getSDKVersionName();
}
/**
* 获取Android API级别
*/
public static int getSDKVersionCode() {
return DeviceUtils.getSDKVersionCode();
}
/**
* 判断设备是否为平板
*/
public static boolean isTablet() {
return DeviceUtils.isTablet();
}
/**
* 获取设备信息摘要
*/
public static String getDeviceInfoSummary() {
return String.format("设备信息 - 型号: %s, 制造商: %s, Android: %s(API %d), 平板: %s",
getModel(), getManufacturer(), getSDKVersionName(),
getSDKVersionCode(), isTablet() ? "是" : "否");
}
}
/**
* 屏幕信息相关工具方法
*/
public static class Screen {
/**
* 获取屏幕宽度(像素)
*/
public static int getScreenWidth() {
return ScreenUtils.getScreenWidth();
}
/**
* 获取屏幕高度(像素)
*/
public static int getScreenHeight() {
return ScreenUtils.getScreenHeight();
}
/**
* 获取屏幕密度
*/
public static float getScreenDensity() {
return ScreenUtils.getScreenDensity();
}
/**
* dp转px
*/
public static int dp2px(float dpValue) {
return com.blankj.utilcode.util.SizeUtils.dp2px(dpValue);
}
/**
* px转dp
*/
public static int px2dp(float pxValue) {
return com.blankj.utilcode.util.SizeUtils.px2dp(pxValue);
}
/**
* 获取屏幕信息摘要
*/
public static String getScreenInfoSummary() {
return String.format("屏幕信息 - 尺寸: %dx%d, 密度: %.2f",
getScreenWidth(), getScreenHeight(), getScreenDensity());
}
}
/**
* 网络相关工具方法
*/
public static class Network {
/**
* 判断网络是否连接
*/
public static boolean isConnected() {
return NetworkUtils.isConnected();
}
/**
* 判断是否为WiFi连接
*/
public static boolean isWifiConnected() {
return NetworkUtils.isWifiConnected();
}
/**
* 判断是否为移动数据连接
*/
public static boolean isMobileData() {
return NetworkUtils.isMobileData();
}
/**
* 获取网络类型
*/
public static NetworkUtils.NetworkType getNetworkType() {
return NetworkUtils.getNetworkType();
}
/**
* 获取网络状态摘要
*/
public static String getNetworkStatusSummary() {
if (!isConnected()) {
return "网络状态 - 未连接";
}
String connectionType = "未知";
if (isWifiConnected()) {
connectionType = "WiFi";
} else if (isMobileData()) {
connectionType = "移动数据";
}
return String.format("网络状态 - 已连接(%s), 类型: %s",
connectionType, getNetworkType());
}
}
/**
* 文件操作相关工具方法
*/
public static class File {
/**
* 获取应用外部存储目录
*/
public static String getAppExternalPath() {
return PathUtils.getExternalAppDataPath();
}
/**
* 获取应用内部存储目录
*/
public static String getAppInternalPath() {
return PathUtils.getInternalAppDataPath();
}
/**
* 创建目录
*/
public static boolean createDir(String dirPath) {
return FileUtils.createOrExistsDir(dirPath);
}
/**
* 判断文件是否存在
*/
public static boolean isFileExists(String filePath) {
return FileUtils.isFileExists(filePath);
}
/**
* 获取文件大小(字节)
*/
public static long getFileSize(String filePath) {
return FileUtils.getFileLength(filePath);
}
/**
* 删除文件或目录
*/
public static boolean delete(String path) {
return FileUtils.delete(path);
}
}
/**
* 时间相关工具方法
*/
public static class Time {
/**
* 获取当前时间戳(毫秒)
*/
public static long getCurrentTimeMillis() {
return System.currentTimeMillis();
}
/**
* 时间戳转字符串(默认格式: yyyy-MM-dd HH:mm:ss)
*/
public static String millis2String(long millis) {
return TimeUtils.millis2String(millis);
}
/**
* 时间戳转字符串(自定义格式)
*/
public static String millis2String(long millis, String pattern) {
return TimeUtils.millis2String(millis, pattern);
}
/**
* 字符串转时间戳
*/
public static long string2Millis(String time, String pattern) {
return TimeUtils.string2Millis(time, pattern);
}
/**
* 获取友好的时间描述
*/
public static String getFriendlyTimeSpanByNow(long millis) {
return TimeUtils.getFriendlyTimeSpanByNow(millis);
}
}
/**
* Toast相关工具方法
*/
public static class Toast {
/**
* 显示短时间Toast
*/
public static void showShort(String message) {
ToastUtils.showShort(message);
}
/**
* 显示长时间Toast
*/
public static void showLong(String message) {
ToastUtils.showLong(message);
}
/**
* 取消Toast显示
*/
public static void cancel() {
ToastUtils.cancel();
}
}
/**
* 手机相关工具方法
*/
public static class Phone {
/**
* 判断设备是否为手机
*/
public static boolean isPhone() {
return PhoneUtils.isPhone();
}
/**
* 获取IMEI(需要权限)
*/
public static String getIMEI() {
try {
return PhoneUtils.getIMEI();
} catch (Exception e) {
LogManager.logWarning(TAG, "获取IMEI失败: " + e.getMessage());
return "";
}
}
/**
* 获取手机型号
*/
public static String getPhoneType() {
return PhoneUtils.getPhoneType() + "";
}
}
/**
* 系统信息汇总
* 用于24小时无人值守应用的系统状态记录
*/
public static String getSystemInfoSummary() {
StringBuilder summary = new StringBuilder();
summary.append("=== 系统信息汇总 ===\n");
summary.append(App.getAppInfoSummary()).append("\n");
summary.append(Device.getDeviceInfoSummary()).append("\n");
summary.append(Screen.getScreenInfoSummary()).append("\n");
summary.append(Network.getNetworkStatusSummary()).append("\n");
summary.append("当前时间: ").append(Time.millis2String(Time.getCurrentTimeMillis())).append("\n");
summary.append("应用前台状态: ").append(App.isAppForeground() ? "是" : "否").append("\n");
summary.append("==================");
return summary.toString();
}
/**
* 记录系统信息到日志
*/
public static void logSystemInfo() {
String systemInfo = getSystemInfoSummary();
LogManager.logOperation(TAG, systemInfo);
}
}

16
gradle.properties

@ -26,3 +26,19 @@ android.nonTransitiveRClass=true
org.gradle.offline=false org.gradle.offline=false
# Android SDK path # Android SDK path
android.sdk.path=/Users/zmt/Library/Android/sdk android.sdk.path=/Users/zmt/Library/Android/sdk
# 24小时运行优化配置
# 增大Gradle内存分配
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
# 并行构建优化
org.gradle.parallel=true
# 启用守护进程
org.gradle.daemon=true
# 配置缓存
org.gradle.caching=true
# Java版本兼容性配置
# 抑制不兼容警告
android.javaCompile.suppressSourceTargetDeprecationWarning=true
# 启用R8优化
android.enableR8.fullMode=false
Loading…
Cancel
Save