移除提醒线程前台标志

This commit is contained in:
2025-12-18 13:11:00 +08:00
parent 5e6de91430
commit b3f4571b57
4 changed files with 110 additions and 150 deletions

View File

@@ -132,8 +132,8 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
if (mADsBannerView != null) {
mADsBannerView.resumeADs(this);
}
// 设置RemindThread前台状态
setRemindThreadForeground(true);
// // 设置RemindThread前台状态
// setRemindThreadForeground(true);
LogUtils.d(TAG, "onResume: 退出");
}
@@ -141,8 +141,8 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
protected void onPause() {
LogUtils.d(TAG, "onPause: 进入");
super.onPause();
// 设置RemindThread后台状态
setRemindThreadForeground(false);
// // 设置RemindThread后台状态
// setRemindThreadForeground(false);
LogUtils.d(TAG, "onPause: 退出");
}
@@ -521,19 +521,19 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
/**
* 设置线程前后台状态(依赖服务运行状态)
*/
private void setRemindThreadForeground(boolean isForeground) {
LogUtils.d(TAG, "setRemindThreadForeground: 进入,前台状态=" + isForeground);
if (!ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName())) {
LogUtils.w(TAG, "setRemindThreadForeground: 服务未运行,跳过状态设置");
return;
}
try {
RemindThread.getInstance(getApplicationContext(), null).setAppForeground(isForeground);
} catch (IllegalArgumentException e) {
LogUtils.w(TAG, "setRemindThreadForeground: 线程未初始化", e);
}
LogUtils.d(TAG, "setRemindThreadForeground: 退出");
}
// private void setRemindThreadForeground(boolean isForeground) {
// LogUtils.d(TAG, "setRemindThreadForeground: 进入,前台状态=" + isForeground);
// if (!ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName())) {
// LogUtils.w(TAG, "setRemindThreadForeground: 服务未运行,跳过状态设置");
// return;
// }
// try {
// RemindThread.getInstance(getApplicationContext(), null).setAppForeground(isForeground);
// } catch (IllegalArgumentException e) {
// LogUtils.w(TAG, "setRemindThreadForeground: 线程未初始化", e);
// }
// LogUtils.d(TAG, "setRemindThreadForeground: 退出");
// }
/**
* 切换服务启用状态仅持久化本地配置点击UI开关时不联动服务启停

View File

@@ -35,8 +35,8 @@ public class ControlCenterService extends Service {
public static final String ACTION_RESTART_REMIND_THREAD = "cc.winboll.studio.powerbell.action.RESTART_REMIND_THREAD";
public static final String EXTRA_APP_CONFIG_BEAN = "cc.winboll.studio.powerbell.extra.APP_CONFIG_BEAN";
// 新增:应用前台/后台状态同步指令用于MainActivity与服务联动
public static final String ACTION_SYNC_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.action.SYNC_APP_FOREGROUND_STATE";
public static final String EXTRA_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.extra.APP_FOREGROUND_STATE";
// public static final String ACTION_SYNC_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.action.SYNC_APP_FOREGROUND_STATE";
// public static final String EXTRA_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.extra.APP_FOREGROUND_STATE";
// ================================== 核心成员变量(按依赖优先级排序,私有封装)=================================
// 服务控制核心本地持久化管理替代Intent传递
@@ -93,8 +93,8 @@ public class ControlCenterService extends Service {
handleExternalCommand(intent);
// ================================== 【修复点2删除rebindForegroundNotify(),避免重复调用】=================================
initServiceBusinessIfNeed(); // 按需初始化业务(避免重复初始化)
// 新增:业务初始化完成后,同步应用前台状态到线程(防止状态丢失)
syncAppForegroundStateToThread();
// // 新增:业务初始化完成后,同步应用前台状态到线程(防止状态丢失)
// syncAppForegroundStateToThread();
LogUtils.d(TAG, "onStartCommand: 核心逻辑执行完成返回START_STICKY");
return START_STICKY;
} else {
@@ -373,8 +373,8 @@ public class ControlCenterService extends Service {
mRemindThread = RemindThread.getInstance(this, mServiceHandler);
// 同步配置并开启提醒
syncConfigToRemindThread();
// 新增:同步应用前台状态(确保新线程启动时状态正确)
syncAppForegroundStateToThread();
// // 新增:同步应用前台状态(确保新线程启动时状态正确)
// syncAppForegroundStateToThread();
// 双重校验,避免线程重复启动
if (mRemindThread != null && !mRemindThread.isAlive() && !mRemindThread.isThreadStarted()) {
@@ -454,18 +454,18 @@ public class ControlCenterService extends Service {
* 新增同步应用前台状态到RemindThread核心联动逻辑
* 确保线程实时感知应用前台/后台状态,控制提醒开关
*/
private void syncAppForegroundStateToThread() {
LogUtils.d(TAG, "syncAppForegroundStateToThread: 同步前台状态,当前状态=" + mIsAppForeground);
synchronized (mServiceLock) {
if (mRemindThread == null || mIsDestroyed || !isServiceRunning) {
LogUtils.w(TAG, "syncAppForegroundStateToThread: 线程未启动/服务已销毁,同步失败");
return;
}
// 调用RemindThread新增方法同步前台状态线程安全
mRemindThread.setAppForeground(mIsAppForeground);
LogUtils.d(TAG, "syncAppForegroundStateToThread: 前台状态同步完成");
}
}
// private void syncAppForegroundStateToThread() {
// LogUtils.d(TAG, "syncAppForegroundStateToThread: 同步前台状态,当前状态=" + mIsAppForeground);
// synchronized (mServiceLock) {
// if (mRemindThread == null || mIsDestroyed || !isServiceRunning) {
// LogUtils.w(TAG, "syncAppForegroundStateToThread: 线程未启动/服务已销毁,同步失败");
// return;
// }
// // 调用RemindThread新增方法同步前台状态线程安全
// mRemindThread.setAppForeground(mIsAppForeground);
// LogUtils.d(TAG, "syncAppForegroundStateToThread: 前台状态同步完成");
// }
// }
// ================================== 外部指令处理方法(新增前台状态同步指令,完善链路)=================================
/**
@@ -503,15 +503,16 @@ public class ControlCenterService extends Service {
LogUtils.w(TAG, "handleExternalCommand: 服务已禁用,忽略线程重启指令");
}
}
} else if (ACTION_SYNC_APP_FOREGROUND_STATE.equals(action)) {
boolean isForeground = intent.getBooleanExtra(EXTRA_APP_FOREGROUND_STATE, false);
synchronized (mServiceLock) {
mIsAppForeground = isForeground;
LogUtils.d(TAG, "handleExternalCommand: 收到前台状态同步指令,更新状态=" + isForeground);
// 同步状态到线程(实时生效)
syncAppForegroundStateToThread();
}
}
}
// else if (ACTION_SYNC_APP_FOREGROUND_STATE.equals(action)) {
// boolean isForeground = intent.getBooleanExtra(EXTRA_APP_FOREGROUND_STATE, false);
// synchronized (mServiceLock) {
// mIsAppForeground = isForeground;
// LogUtils.d(TAG, "handleExternalCommand: 收到前台状态同步指令,更新状态=" + isForeground);
// // 同步状态到线程(实时生效)
// syncAppForegroundStateToThread();
// }
// }
LogUtils.d(TAG, "handleExternalCommand: 外部指令处理完成");
}
@@ -634,34 +635,34 @@ public class ControlCenterService extends Service {
* @param context 上下文
* @param isForeground true=前台false=后台
*/
public static void syncAppForegroundState(Context context, boolean isForeground) {
LogUtils.d(TAG, "syncAppForegroundState: 发送前台状态同步指令,状态=" + isForeground);
if (context == null) {
LogUtils.e(TAG, "syncAppForegroundState: Context为空同步失败");
return;
}
if (!isServiceRunning(context, ControlCenterService.class)) {
LogUtils.w(TAG, "syncAppForegroundState: 服务未运行,跳过同步");
return;
}
Intent intent = new Intent(context, ControlCenterService.class);
intent.setAction(ACTION_SYNC_APP_FOREGROUND_STATE);
intent.putExtra(EXTRA_APP_FOREGROUND_STATE, isForeground);
intent.setPackage(context.getPackageName());
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
LogUtils.d(TAG, "syncAppForegroundState: 前台状态同步指令发送成功");
} catch (Exception e) {
LogUtils.e(TAG, "syncAppForegroundState: 发送同步指令异常", e);
}
}
// public static void syncAppForegroundState(Context context, boolean isForeground) {
// LogUtils.d(TAG, "syncAppForegroundState: 发送前台状态同步指令,状态=" + isForeground);
// if (context == null) {
// LogUtils.e(TAG, "syncAppForegroundState: Context为空同步失败");
// return;
// }
// if (!isServiceRunning(context, ControlCenterService.class)) {
// LogUtils.w(TAG, "syncAppForegroundState: 服务未运行,跳过同步");
// return;
// }
//
// Intent intent = new Intent(context, ControlCenterService.class);
// intent.setAction(ACTION_SYNC_APP_FOREGROUND_STATE);
// intent.putExtra(EXTRA_APP_FOREGROUND_STATE, isForeground);
// intent.setPackage(context.getPackageName());
// intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
//
// try {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context.startForegroundService(intent);
// } else {
// context.startService(intent);
// }
// LogUtils.d(TAG, "syncAppForegroundState: 前台状态同步指令发送成功");
// } catch (Exception e) {
// LogUtils.e(TAG, "syncAppForegroundState: 发送同步指令异常", e);
// }
// }
/**
* 判断服务是否运行适配API30+ ActivityManager限制优化判断逻辑
@@ -865,12 +866,12 @@ public class ControlCenterService extends Service {
}
// 新增:设置应用前台状态(内部/外部调用,同步到线程)
public void setAppForeground(boolean isForeground) {
LogUtils.d(TAG, "setAppForeground: 更新应用前台状态=" + isForeground);
synchronized (mServiceLock) {
mIsAppForeground = isForeground;
syncAppForegroundStateToThread();
}
}
// public void setAppForeground(boolean isForeground) {
// LogUtils.d(TAG, "setAppForeground: 更新应用前台状态=" + isForeground);
// synchronized (mServiceLock) {
// mIsAppForeground = isForeground;
// syncAppForegroundStateToThread();
// }
// }
}

View File

@@ -18,10 +18,10 @@ public class RemindThread extends Thread {
private static final long INIT_DELAY_TIME = 500L; // 初始化延迟ms等待服务就绪
private static final int MIN_SLEEP_TIME = 500; // 最小检测间隔ms防高频轮询
private static final int DEFAULT_SLEEP_TIME = 1000; // 默认检测间隔ms
private static final long REMIND_INTERVAL = 3000L; // 重复提醒间隔ms防骚扰
private static final long REMIND_INTERVAL = 3000L; // 重复提醒间隔ms防骚扰
private static final int CONFIG_RETRY_MAX = 3; // 配置同步重试次数(兜底)
private static final int INVALID_BATTERY_VALUE = -1; // 无效电量标记(新增)
private static final long BACKGROUND_SLEEP_TIME = 5000L;// 后台休眠间隔ms减少资源占用,新增
private static final int INVALID_BATTERY_VALUE = -1; // 无效电量标记
private static final long BACKGROUND_SLEEP_TIME = 5000L;// 后台休眠间隔ms减少资源占用
// ================================== 单例核心(线程安全,避免复用旧实例)=================================
private static volatile RemindThread sInstance;
@@ -36,7 +36,6 @@ public class RemindThread extends Thread {
private volatile boolean isThreadStarted; // 启动标记区分isAlive()
private volatile boolean isReminding; // 全局提醒开关
private volatile boolean isRemindTimerRunning; // 提醒恢复计时器状态
private volatile boolean isAppForeground; // 应用前台状态(新增:控制提醒开关)
// 业务配置(实时同步,范围校验)
private volatile boolean isEnableChargeReminder; // 充电提醒开关
@@ -105,7 +104,7 @@ public class RemindThread extends Thread {
}
}
// ================================== 线程核心逻辑run方法高效退出+异常容错+前台判断=================================
// ================================== 线程核心逻辑run方法高效退出+异常容错)=================================
@Override
public void run() {
LogUtils.d(TAG, "线程启动ID" + Thread.currentThread().getId() + ",状态:" + getState());
@@ -117,7 +116,6 @@ public class RemindThread extends Thread {
}
isThreadStarted = true;
lastRemindTime = 0;
isAppForeground = true; // 初始默认前台(窗口打开状态)
}
// 配置同步重试(失败则兜底默认值)
@@ -142,19 +140,14 @@ public class RemindThread extends Thread {
return;
}
// 核心检测循环(快速退出+并发安全+前台判断
// 核心检测循环(快速退出+并发安全)
LogUtils.d(TAG, "进入电量检测循环,间隔:" + sleepTime + "ms");
while (!isExist) {
try {
if (isExist) break;
// 核心防护:应用后台/提醒关闭/电量无效,直接休眠(跳过提醒检测)
// 核心防护:提醒关闭/电量无效,直接休眠(跳过提醒检测)
synchronized (mLock) {
// 应用后台:延长休眠间隔,减少资源占用+停止提醒
if (!isAppForeground) {
safeSleep(BACKGROUND_SLEEP_TIME);
continue;
}
// 提醒关闭/电量无效:正常休眠,不检测
if (!isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
safeSleep(sleepTime);
@@ -169,9 +162,9 @@ public class RemindThread extends Thread {
}
}
// 锁保护核心提醒逻辑(仅前台+提醒开启+电量有效时执行)
// 锁保护核心提醒逻辑(仅提醒开启+电量有效时执行)
synchronized (mLock) {
if (isExist || !isAppForeground || !isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
if (isExist || !isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
safeSleep(sleepTime);
continue;
}
@@ -219,8 +212,8 @@ public class RemindThread extends Thread {
int retryCount = 0;
while (retryCount < CONFIG_RETRY_MAX) {
synchronized (mLock) {
if ((chargeReminderValue >= 0 && chargeReminderValue <= 100)
&& (usageReminderValue >= 0 && usageReminderValue <= 100)) {
if ((chargeReminderValue >= 0 && chargeReminderValue <= 100)
&& (usageReminderValue >= 0 && usageReminderValue <= 100)) {
LogUtils.d(TAG, "配置同步成功,重试次数:" + retryCount);
return true;
}
@@ -253,9 +246,9 @@ public class RemindThread extends Thread {
*/
private void sendNotificationMessage(String type, int battery, boolean isCharging) {
LogUtils.d(TAG, "准备发送提醒消息:类型=" + type + ",电量=" + battery + ",充电状态=" + isCharging);
// 双重防护:线程退出/应用后台/提醒关闭,跳过发送
if (isExist || !isAppForeground || !isReminding) {
LogUtils.d(TAG, "线程退出/应用后台/提醒关闭,跳过发送");
// 双重防护:线程退出/提醒关闭,跳过发送
if (isExist || !isReminding) {
LogUtils.d(TAG, "线程退出/提醒关闭,跳过发送");
return;
}
@@ -285,7 +278,7 @@ public class RemindThread extends Thread {
private void startRemindRecoveryTimer() {
LogUtils.d(TAG, "启动提醒恢复计时器,间隔:" + REMIND_INTERVAL + "ms");
synchronized (mLock) {
if (isExist || isRemindTimerRunning || sInstance != this || !isAppForeground) {
if (isExist || isRemindTimerRunning || sInstance != this) {
LogUtils.w(TAG, "计时器启动条件不满足,跳过");
return;
}
@@ -306,9 +299,9 @@ public class RemindThread extends Thread {
}
synchronized (thread.mLock) {
// 仅前台+有启用提醒时,才恢复提醒
if (!thread.isExist && sInstance == thread && thread.isAppForeground
&& (thread.isEnableChargeReminder || thread.isEnableUsageReminder)) {
// 仅线程存活+有启用提醒时,才恢复提醒
if (!thread.isExist && sInstance == thread
&& (thread.isEnableChargeReminder || thread.isEnableUsageReminder)) {
thread.isReminding = true;
LogUtils.d(TAG, "提醒功能恢复开启");
}
@@ -339,7 +332,6 @@ public class RemindThread extends Thread {
isExist = true;
isReminding = false;
isRemindTimerRunning = false;
isAppForeground = false; // 标记后台,强制停止提醒
}
if (isAlive()) {
interrupt();
@@ -379,7 +371,6 @@ public class RemindThread extends Thread {
isExist = true;
isThreadStarted = false;
isRemindTimerRunning = false;
isAppForeground = false;
lastRemindTime = 0;
quantityOfElectricity = INVALID_BATTERY_VALUE; // 重置为无效电量,防残留
}
@@ -399,7 +390,6 @@ public class RemindThread extends Thread {
isReminding = false;
isThreadStarted = false;
isRemindTimerRunning = false;
isAppForeground = false;
lastRemindTime = 0;
// 业务配置
isEnableChargeReminder = false;
@@ -421,7 +411,7 @@ public class RemindThread extends Thread {
isExist = false;
isRemindTimerRunning = false;
lastRemindTime = 0;
isReminding = (isEnableChargeReminder || isEnableUsageReminder) && isAppForeground; // 仅前台时开启提醒
isReminding = (isEnableChargeReminder || isEnableUsageReminder); // 根据开关自动开启提醒
}
LogUtils.d(TAG, "运行状态重置完成,全局提醒:" + isReminding);
}
@@ -452,13 +442,13 @@ public class RemindThread extends Thread {
int currentBattery = config.getCurrentBatteryValue();
quantityOfElectricity = (currentBattery >= 0 && currentBattery <= 100) ? currentBattery : INVALID_BATTERY_VALUE;
isCharging = config.isCharging();
// 提醒开关:前台+有启用提醒才开启
isReminding = (isEnableChargeReminder || isEnableUsageReminder) && isAppForeground;
// 提醒开关:根据配置自动开启
isReminding = (isEnableChargeReminder || isEnableUsageReminder);
}
LogUtils.d(TAG, "配置同步完成:检测间隔" + sleepTime + "ms全局提醒" + isReminding + ",当前电量" + quantityOfElectricity);
}
// ================================== Setter/Getter锁保护线程安全+精准日志,新增前台状态控制=================================
// ================================== Setter/Getter锁保护线程安全+精准日志)=================================
public boolean isExist() {
synchronized (mLock) {
return isExist;
@@ -480,32 +470,8 @@ public class RemindThread extends Thread {
public void setIsReminding(boolean isReminding) {
synchronized (mLock) {
// 仅前台时可开启提醒
this.isReminding = isReminding && isAppForeground;
LogUtils.d(TAG, "设置全局提醒开关:" + this.isReminding + "(应用前台状态:" + isAppForeground + "");
}
}
// 新增:应用前台/后台状态设置(主窗口关闭/打开时调用)
public void setAppForeground(boolean isForeground) {
synchronized (mLock) {
this.isAppForeground = isForeground;
// 后台时强制关闭提醒,前台时根据开关自动开启
if (!isForeground) {
this.isReminding = false;
this.quantityOfElectricity = INVALID_BATTERY_VALUE; // 后台重置为无效电量
LogUtils.d(TAG, "应用切换到后台,停止提醒+重置无效电量");
} else {
this.isReminding = (isEnableChargeReminder || isEnableUsageReminder);
LogUtils.d(TAG, "应用切换到前台,提醒状态:" + this.isReminding);
}
}
}
// 新增:获取应用前台状态
public boolean isAppForeground() {
synchronized (mLock) {
return isAppForeground;
this.isReminding = isReminding;
LogUtils.d(TAG, "设置全局提醒开关:" + this.isReminding);
}
}
@@ -524,7 +490,7 @@ public class RemindThread extends Thread {
public void setIsEnableUsageReminder(boolean isEnableUsageReminder) {
synchronized (mLock) {
this.isEnableUsageReminder = isEnableUsageReminder;
isReminding = (isEnableChargeReminder || isEnableUsageReminder) && isAppForeground;
isReminding = (isEnableChargeReminder || isEnableUsageReminder);
LogUtils.d(TAG, "设置耗电提醒开关:" + isEnableUsageReminder + ",全局提醒:" + isReminding);
}
}
@@ -538,7 +504,7 @@ public class RemindThread extends Thread {
public void setIsEnableChargeReminder(boolean isEnableChargeReminder) {
synchronized (mLock) {
this.isEnableChargeReminder = isEnableChargeReminder;
isReminding = (isEnableChargeReminder || isEnableUsageReminder) && isAppForeground;
isReminding = (isEnableChargeReminder || isEnableUsageReminder);
LogUtils.d(TAG, "设置充电提醒开关:" + isEnableChargeReminder + ",全局提醒:" + isReminding);
}
}
@@ -590,14 +556,8 @@ public class RemindThread extends Thread {
public void setQuantityOfElectricity(int quantityOfElectricity) {
synchronized (mLock) {
// 仅前台时更新电量,后台直接设为无效
if (isAppForeground) {
this.quantityOfElectricity = Math.min(Math.max(quantityOfElectricity, 0), 100);
LogUtils.d(TAG, "更新当前电量:" + this.quantityOfElectricity);
} else {
this.quantityOfElectricity = INVALID_BATTERY_VALUE;
LogUtils.w(TAG, "应用后台,不更新电量,标记为无效");
}
this.quantityOfElectricity = Math.min(Math.max(quantityOfElectricity, 0), 100);
LogUtils.d(TAG, "更新当前电量:" + this.quantityOfElectricity);
}
}
@@ -618,7 +578,7 @@ public class RemindThread extends Thread {
public boolean isRunning() {
synchronized (mLock) {
boolean running = !isExist && isThreadStarted && isAlive();
LogUtils.d(TAG, "线程运行状态:" + running + "(退出:" + isExist + ",已启动:" + isThreadStarted + ",存活:" + isAlive() + ",前台:" + isAppForeground + "");
LogUtils.d(TAG, "线程运行状态:" + running + "(退出:" + isExist + ",已启动:" + isThreadStarted + ",存活:" + isAlive() + "");
return running;
}
}
@@ -644,7 +604,6 @@ public class RemindThread extends Thread {
"threadId=" + getId() +
", threadName='" + getName() + '\'' +
", isRunning=" + isRunning() +
", isForeground=" + isAppForeground() +
", isReminding=" + isReminding() +
", chargeThreshold=" + getChargeReminderValue() +
", usageThreshold=" + getUsageReminderValue() +