正在修复电量提醒线程。。。
This commit is contained in:
@@ -38,9 +38,9 @@ public class RemindThread extends Thread {
|
|||||||
|
|
||||||
// 线程状态标记(volatile 保证多线程可见性)
|
// 线程状态标记(volatile 保证多线程可见性)
|
||||||
private volatile boolean isExist;
|
private volatile boolean isExist;
|
||||||
private volatile boolean isThreadStarted;
|
//private volatile boolean isThreadStarted;
|
||||||
private volatile boolean isReminding;
|
private volatile boolean isReminding;
|
||||||
private volatile boolean isRemindTimerRunning;
|
//private volatile boolean isRemindTimerRunning;
|
||||||
|
|
||||||
// 业务配置参数(范围校验,实时同步)
|
// 业务配置参数(范围校验,实时同步)
|
||||||
private volatile boolean isEnableChargeReminder;
|
private volatile boolean isEnableChargeReminder;
|
||||||
@@ -52,7 +52,7 @@ public class RemindThread extends Thread {
|
|||||||
private volatile boolean isCharging;
|
private volatile boolean isCharging;
|
||||||
|
|
||||||
// 辅助变量(并发安全+防重复提醒)
|
// 辅助变量(并发安全+防重复提醒)
|
||||||
private volatile long lastRemindTime;
|
//private volatile long lastRemindTime;
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
// ================================== 私有构造器(单例专用,初始化状态+防护泄漏)=================================
|
// ================================== 私有构造器(单例专用,初始化状态+防护泄漏)=================================
|
||||||
@@ -80,7 +80,9 @@ public class RemindThread extends Thread {
|
|||||||
|
|
||||||
// 1. 若 isReminding 为真,直接返回 true 无需操作
|
// 1. 若 isReminding 为真,直接返回 true 无需操作
|
||||||
if (sInstance != null && sInstance.isReminding) {
|
if (sInstance != null && sInstance.isReminding) {
|
||||||
LogUtils.d(TAG, "startRemindThread: isReminding为true,直接返回");
|
// 3. 同步配置
|
||||||
|
sInstance.setAppConfigBean(config);
|
||||||
|
LogUtils.d(TAG, "startRemindThread: isReminding 为真,更新最新数据后返回");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +95,6 @@ public class RemindThread extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 同步配置
|
|
||||||
sInstance.setAppConfigBean(config);
|
|
||||||
|
|
||||||
// 4. 线程未运行则启动
|
// 4. 线程未运行则启动
|
||||||
if (!sInstance.isRunning()) {
|
if (!sInstance.isRunning()) {
|
||||||
@@ -121,29 +121,29 @@ public class RemindThread extends Thread {
|
|||||||
/**
|
/**
|
||||||
* 获取单例实例(私有化,仅内部调用)
|
* 获取单例实例(私有化,仅内部调用)
|
||||||
*/
|
*/
|
||||||
private static RemindThread getInstance(Context context, ControlCenterServiceHandler handler) {
|
// private static RemindThread getInstance(Context context, ControlCenterServiceHandler handler) {
|
||||||
LogUtils.d(TAG, "getInstance: 尝试获取单例 | currentInstance=" + (sInstance != null ? "存在" : "不存在"));
|
// LogUtils.d(TAG, "getInstance: 尝试获取单例 | currentInstance=" + (sInstance != null ? "存在" : "不存在"));
|
||||||
|
//
|
||||||
if (context == null || handler == null) {
|
// if (context == null || handler == null) {
|
||||||
LogUtils.e(TAG, "getInstance: 入参为空");
|
// LogUtils.e(TAG, "getInstance: 入参为空");
|
||||||
throw new IllegalArgumentException("Context and ControlCenterServiceHandler cannot be null");
|
// throw new IllegalArgumentException("Context and ControlCenterServiceHandler cannot be null");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (sInstance != null && !sInstance.isRunning()) {
|
// if (sInstance != null && !sInstance.isRunning()) {
|
||||||
destroyInstance();
|
// destroyInstance();
|
||||||
LogUtils.d(TAG, "getInstance: 旧线程已停止,销毁单例");
|
// LogUtils.d(TAG, "getInstance: 旧线程已停止,销毁单例");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (sInstance == null) {
|
// if (sInstance == null) {
|
||||||
synchronized (RemindThread.class) {
|
// synchronized (RemindThread.class) {
|
||||||
if (sInstance == null) {
|
// if (sInstance == null) {
|
||||||
sInstance = new RemindThread(context, handler);
|
// sInstance = new RemindThread(context, handler);
|
||||||
LogUtils.d(TAG, "getInstance: 新线程实例创建成功 | threadId=" + sInstance.getId());
|
// LogUtils.d(TAG, "getInstance: 新线程实例创建成功 | threadId=" + sInstance.getId());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return sInstance;
|
// return sInstance;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 销毁单例(安全停止线程+释放资源,避免内存泄漏)
|
* 销毁单例(安全停止线程+释放资源,避免内存泄漏)
|
||||||
@@ -153,14 +153,14 @@ public class RemindThread extends Thread {
|
|||||||
synchronized (RemindThread.class) {
|
synchronized (RemindThread.class) {
|
||||||
if (sInstance != null) {
|
if (sInstance != null) {
|
||||||
sInstance.isExist = true;
|
sInstance.isExist = true;
|
||||||
sInstance.isReminding = false;
|
//sInstance.isRemindTimerRunning = false;
|
||||||
sInstance.isRemindTimerRunning = false;
|
|
||||||
if (sInstance.isAlive()) {
|
if (sInstance.isAlive()) {
|
||||||
sInstance.interrupt();
|
sInstance.interrupt();
|
||||||
LogUtils.d(TAG, "destroyInstance: 线程已中断");
|
LogUtils.d(TAG, "destroyInstance: 线程已中断");
|
||||||
}
|
}
|
||||||
sInstance.releaseResourcesInternal();
|
sInstance.releaseResourcesInternal();
|
||||||
sInstance = null;
|
sInstance = null;
|
||||||
|
sInstance.isReminding = false;
|
||||||
LogUtils.d(TAG, "destroyInstance: 线程单例销毁完成");
|
LogUtils.d(TAG, "destroyInstance: 线程单例销毁完成");
|
||||||
} else {
|
} else {
|
||||||
LogUtils.w(TAG, "destroyInstance: 单例已为空,跳过销毁");
|
LogUtils.w(TAG, "destroyInstance: 单例已为空,跳过销毁");
|
||||||
@@ -175,55 +175,11 @@ public class RemindThread extends Thread {
|
|||||||
|
|
||||||
// 仅保留此处的mLock,保护isReminding等核心状态的读写,防止线程重复启动
|
// 仅保留此处的mLock,保护isReminding等核心状态的读写,防止线程重复启动
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (isThreadStarted || isExist) {
|
if (isExist && !isReminding) {
|
||||||
LogUtils.e(TAG, "run: 线程重复启动 | isThreadStarted=" + isThreadStarted + " | isExist=" + isExist);
|
isReminding = true;
|
||||||
return;
|
} else {
|
||||||
}
|
LogUtils.d(TAG, String.format("线程退出,标志位:isExist %s, isReminding %s.", isExist, isReminding));
|
||||||
isThreadStarted = true;
|
}
|
||||||
lastRemindTime = 0;
|
|
||||||
// 确保isReminding初始状态正确
|
|
||||||
isReminding = isEnableChargeReminder || isEnableUsageReminder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置同步重试(失败则兜底默认值)
|
|
||||||
boolean configValid = syncConfigRetry();
|
|
||||||
if (!configValid) {
|
|
||||||
LogUtils.e(TAG, "run: 配置同步失败,使用兜底阈值启动");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化延迟(等待服务就绪)
|
|
||||||
try {
|
|
||||||
LogUtils.d(TAG, "run: 初始化延迟 | delayTime=" + INIT_DELAY_TIME + "ms");
|
|
||||||
Thread.sleep(INIT_DELAY_TIME);
|
|
||||||
if (isExist) {
|
|
||||||
LogUtils.d(TAG, "run: 延迟期间收到退出指令,线程终止");
|
|
||||||
cleanThreadStateInternal();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
LogUtils.e(TAG, "run: 初始化延迟被中断,线程终止", e);
|
|
||||||
cleanThreadStateInternal();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 新增:首次电量检测,立即触发符合条件的提醒 =====================
|
|
||||||
LogUtils.d(TAG, "run: 执行首次电量检测");
|
|
||||||
if (!isExist && isReminding && quantityOfElectricity != INVALID_BATTERY_VALUE) {
|
|
||||||
// 充电提醒:充电中 + 充电提醒开启 + 电量≥阈值
|
|
||||||
if (isCharging && isEnableChargeReminder && quantityOfElectricity >= chargeReminderValue) {
|
|
||||||
LogUtils.d(TAG, "run: 首次检测触发充电提醒 | battery=" + quantityOfElectricity + " ≥ threshold=" + chargeReminderValue);
|
|
||||||
sendNotificationMessageInternal("+", quantityOfElectricity, isCharging);
|
|
||||||
lastRemindTime = System.currentTimeMillis();
|
|
||||||
startRemindRecoveryTimerInternal();
|
|
||||||
}
|
|
||||||
// 耗电提醒:未充电 + 耗电提醒开启 + 电量≤阈值
|
|
||||||
else if (!isCharging && isEnableUsageReminder && quantityOfElectricity <= usageReminderValue) {
|
|
||||||
LogUtils.d(TAG, "run: 首次检测触发耗电提醒 | battery=" + quantityOfElectricity + " ≤ threshold=" + usageReminderValue);
|
|
||||||
sendNotificationMessageInternal("-", quantityOfElectricity, isCharging);
|
|
||||||
lastRemindTime = System.currentTimeMillis();
|
|
||||||
startRemindRecoveryTimerInternal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心检测循环(快速退出+并发安全)
|
// 核心检测循环(快速退出+并发安全)
|
||||||
@@ -232,17 +188,15 @@ public class RemindThread extends Thread {
|
|||||||
try {
|
try {
|
||||||
if (isExist) break;
|
if (isExist) break;
|
||||||
|
|
||||||
// 核心防护:提醒关闭/电量无效,直接休眠(依赖volatile保证可见性)
|
// 核心防护:电量无效退出
|
||||||
if (!isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
|
if ((quantityOfElectricity == INVALID_BATTERY_VALUE)
|
||||||
safeSleepInternal(sleepTime);
|
break;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// 电量超出范围:修正为无效值
|
|
||||||
|
// 电量超出范围退出
|
||||||
if (quantityOfElectricity < 0 || quantityOfElectricity > 100) {
|
if (quantityOfElectricity < 0 || quantityOfElectricity > 100) {
|
||||||
LogUtils.w(TAG, "run: 电量无效,修正为无效值 | currentBattery=" + quantityOfElectricity);
|
LogUtils.w(TAG, "run: 电量无效,修正为无效值 | currentBattery=" + quantityOfElectricity);
|
||||||
quantityOfElectricity = INVALID_BATTERY_VALUE;
|
break;
|
||||||
safeSleepInternal(sleepTime);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 防重复提醒(间隔未到/计时器运行中,依赖volatile保证可见性)
|
// 防重复提醒(间隔未到/计时器运行中,依赖volatile保证可见性)
|
||||||
@@ -258,9 +212,7 @@ public class RemindThread extends Thread {
|
|||||||
sendNotificationMessageInternal("+", quantityOfElectricity, isCharging);
|
sendNotificationMessageInternal("+", quantityOfElectricity, isCharging);
|
||||||
lastRemindTime = currentTime;
|
lastRemindTime = currentTime;
|
||||||
startRemindRecoveryTimerInternal();
|
startRemindRecoveryTimerInternal();
|
||||||
}
|
} else if (!isCharging && isEnableUsageReminder && quantityOfElectricity <= usageReminderValue) {
|
||||||
// 耗电提醒触发
|
|
||||||
else if (!isCharging && isEnableUsageReminder && quantityOfElectricity <= usageReminderValue) {
|
|
||||||
LogUtils.d(TAG, "run: 循环检测触发耗电提醒 | battery=" + quantityOfElectricity + " ≤ threshold=" + usageReminderValue);
|
LogUtils.d(TAG, "run: 循环检测触发耗电提醒 | battery=" + quantityOfElectricity + " ≤ threshold=" + usageReminderValue);
|
||||||
sendNotificationMessageInternal("-", quantityOfElectricity, isCharging);
|
sendNotificationMessageInternal("-", quantityOfElectricity, isCharging);
|
||||||
lastRemindTime = currentTime;
|
lastRemindTime = currentTime;
|
||||||
@@ -283,35 +235,35 @@ public class RemindThread extends Thread {
|
|||||||
/**
|
/**
|
||||||
* 配置同步重试(确保阈值有效,失败兜底)
|
* 配置同步重试(确保阈值有效,失败兜底)
|
||||||
*/
|
*/
|
||||||
private boolean syncConfigRetry() {
|
// private boolean syncConfigRetry() {
|
||||||
LogUtils.d(TAG, "syncConfigRetry: 开始配置同步 | maxRetry=" + CONFIG_RETRY_MAX);
|
// LogUtils.d(TAG, "syncConfigRetry: 开始配置同步 | maxRetry=" + CONFIG_RETRY_MAX);
|
||||||
int retryCount = 0;
|
// int retryCount = 0;
|
||||||
|
//
|
||||||
while (retryCount < CONFIG_RETRY_MAX) {
|
// while (retryCount < CONFIG_RETRY_MAX) {
|
||||||
boolean chargeValid = chargeReminderValue >= 0 && chargeReminderValue <= 100;
|
// boolean chargeValid = chargeReminderValue >= 0 && chargeReminderValue <= 100;
|
||||||
boolean usageValid = usageReminderValue >= 0 && usageReminderValue <= 100;
|
// boolean usageValid = usageReminderValue >= 0 && usageReminderValue <= 100;
|
||||||
if (chargeValid && usageValid) {
|
// if (chargeValid && usageValid) {
|
||||||
LogUtils.d(TAG, "syncConfigRetry: 配置同步成功 | retryCount=" + retryCount);
|
// LogUtils.d(TAG, "syncConfigRetry: 配置同步成功 | retryCount=" + retryCount);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
LogUtils.w(TAG, "syncConfigRetry: 配置未同步,重试 | retryCount=" + (retryCount + 1));
|
// LogUtils.w(TAG, "syncConfigRetry: 配置未同步,重试 | retryCount=" + (retryCount + 1));
|
||||||
try {
|
// try {
|
||||||
Thread.sleep(1000);
|
// Thread.sleep(1000);
|
||||||
retryCount++;
|
// retryCount++;
|
||||||
} catch (InterruptedException e) {
|
// } catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
// Thread.currentThread().interrupt();
|
||||||
LogUtils.e(TAG, "syncConfigRetry: 配置重试被中断", e);
|
// LogUtils.e(TAG, "syncConfigRetry: 配置重试被中断", e);
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 兜底默认阈值
|
// // 兜底默认阈值
|
||||||
chargeReminderValue = (chargeReminderValue < 0 || chargeReminderValue > 100) ? 80 : chargeReminderValue;
|
// chargeReminderValue = (chargeReminderValue < 0 || chargeReminderValue > 100) ? 80 : chargeReminderValue;
|
||||||
usageReminderValue = (usageReminderValue < 0 || usageReminderValue > 100) ? 20 : usageReminderValue;
|
// usageReminderValue = (usageReminderValue < 0 || usageReminderValue > 100) ? 20 : usageReminderValue;
|
||||||
quantityOfElectricity = INVALID_BATTERY_VALUE;
|
// quantityOfElectricity = INVALID_BATTERY_VALUE;
|
||||||
LogUtils.e(TAG, "syncConfigRetry: 配置重试失败,使用兜底阈值 | chargeThreshold=" + chargeReminderValue + " | usageThreshold=" + usageReminderValue);
|
// LogUtils.e(TAG, "syncConfigRetry: 配置重试失败,使用兜底阈值 | chargeThreshold=" + chargeReminderValue + " | usageThreshold=" + usageReminderValue);
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送提醒消息(携带当前电量+充电状态,弱引用Handler+Message复用,防泄漏)
|
* 发送提醒消息(携带当前电量+充电状态,弱引用Handler+Message复用,防泄漏)
|
||||||
|
|||||||
Reference in New Issue
Block a user