剔除服务锁,正在调试RemindThread调用。。。

This commit is contained in:
2025-12-18 15:20:32 +08:00
parent 796d826331
commit d43ba4bff2
3 changed files with 178 additions and 205 deletions

View File

@@ -13,6 +13,7 @@ import android.provider.Settings;
import android.text.TextUtils;
import androidx.core.app.NotificationCompat;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.powerbell.R;
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
import cc.winboll.studio.powerbell.models.AppConfigBean;
@@ -44,29 +45,18 @@ public class ControlCenterService extends Service {
private NotificationManagerUtils mNotificationManager;
private AppConfigBean mCurrentConfigBean;
private NotificationMessage mForegroundNotifyMsg;
// 状态标记
private boolean isServiceRunning;
private boolean mIsDestroyed;
private final Object mServiceLock = new Object();
// 状态标记(复用 isServiceRunning 替代原 isCoreBusinessStarted
private static volatile boolean isServiceRunning;
private static volatile boolean mIsDestroyed;
// ================================== 服务生命周期方法(核心流程入口)=================================
@Override
public void onCreate() {
super.onCreate();
LogUtils.d(TAG, "onCreate: 服务开始创建");
synchronized (mServiceLock) {
isServiceRunning = true;
mIsDestroyed = false;
// 优先发送前台通知避免5秒超时异常
initForegroundNotificationImmediately();
// 加载本地服务控制配置
mServiceControlBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class);
if (mServiceControlBean == null) {
mServiceControlBean = new ControlCenterServiceBean(false);
ControlCenterServiceBean.saveBean(this, mServiceControlBean);
LogUtils.d(TAG, "onCreate: 本地无配置,创建默认禁用配置并持久化");
}
}
// 调用抽取的核心运行函数
runCoreServiceLogic();
LogUtils.d(TAG, "onCreate: 服务创建完成,前台通知已发送,启用状态=" + mServiceControlBean.isEnableService());
}
@@ -75,34 +65,37 @@ public class ControlCenterService extends Service {
LogUtils.d(TAG, "onStartCommand: 服务启动指令触发");
// 读取最新控制配置
loadLatestServiceControlConfig();
synchronized (mServiceLock) {
if (mServiceControlBean.isEnableService()) {
LogUtils.d(TAG, "onStartCommand: 服务已启用,处理外部指令并初始化业务");
handleExternalCommand(intent);
initServiceBusinessIfNeed();
return START_STICKY;
} else {
LogUtils.d(TAG, "onStartCommand: 服务已禁用,停止所有业务");
stopAllBusinessSafely();
return super.onStartCommand(intent, flags, startId);
}
}
// 调用抽取的核心运行函数
runCoreServiceLogic();
if (mServiceControlBean.isEnableService()) {
LogUtils.d(TAG, "onStartCommand: 服务已启用返回START_STICKY");
return START_STICKY;
} else {
return super.onStartCommand(intent, flags, startId);
}
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtils.d(TAG, "onDestroy: 服务开始销毁");
synchronized (mServiceLock) {
isServiceRunning = false;
mIsDestroyed = true;
}
// 顺序释放资源
stopForegroundService();
stopRemindThreadSafely();
destroyHandler();
releaseNotificationResource();
clearAllReferences();
// 重置核心业务标记
mCurrentConfigBean = null;
mForegroundNotifyMsg = null;
// 重置核心业务标记
mServiceHandler = null;
isServiceRunning = false;
mIsDestroyed = true;
LogUtils.d(TAG, "onDestroy: 服务销毁完成");
}
@@ -111,6 +104,38 @@ public class ControlCenterService extends Service {
return null;
}
// ================================== 【核心抽取函数】运行服务核心逻辑 =================================
/**
* 抽取的服务核心运行逻辑统一在onCreate和onStartCommand调用
* 复用 isServiceRunning 做重复运行判断,避免重复初始化业务
*/
private void runCoreServiceLogic() {
loadLatestServiceControlConfig();
// 核心校验:服务已启用 + 服务处于运行状态 + 未被销毁 + 业务未初始化通过mServiceHandler判空
if (mServiceControlBean.isEnableService()) {
if (!isServiceRunning) {
isServiceRunning = true;
mIsDestroyed = false;
LogUtils.d(TAG, "runCoreServiceLogic: 开始执行服务核心业务");
// 初始化通知 + 默认配置 + Handler + 线程
// 优先发送前台通知避免5秒超时异常
initForegroundNotificationImmediately();
// 加载本地服务控制配置
//initNotificationManager();
loadDefaultConfig();
initServiceBusinessLogic();
LogUtils.d(TAG, "runCoreServiceLogic: 核心业务执行完成");
} else {
LogUtils.d(TAG, "runCoreServiceLogic: 核心业务已在运行,无需重复执行");
}
} else {
LogUtils.d(TAG, "runCoreServiceLogic: 服务未启用,不执行核心业务");
}
}
// ================================== 前台通知核心方法(优先执行,防止超时)=================================
/**
* 立即初始化前台通知,内置兜底方案
@@ -128,6 +153,7 @@ public class ControlCenterService extends Service {
mForegroundNotifyMsg.setRemindMSG("service_running");
}
mNotificationManager.startForegroundServiceNotify(this, mForegroundNotifyMsg);
ToastUtils.show("startForegroundServiceNotify 已调用");
LogUtils.d(TAG, "initForegroundNotificationImmediately: 前台通知发送成功ID=" + NotificationManagerUtils.NOTIFY_ID_FOREGROUND_SERVICE);
} catch (Exception e) {
LogUtils.e(TAG, "initForegroundNotificationImmediately: 工具类发送失败,执行兜底方案", e);
@@ -159,81 +185,38 @@ public class ControlCenterService extends Service {
*/
private void loadLatestServiceControlConfig() {
LogUtils.d(TAG, "loadLatestServiceControlConfig: 读取本地配置");
synchronized (mServiceLock) {
ControlCenterServiceBean latestBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class);
if (latestBean != null) {
mServiceControlBean = latestBean;
LogUtils.d(TAG, "loadLatestServiceControlConfig: 配置更新完成,启用状态=" + mServiceControlBean.isEnableService());
} else {
LogUtils.w(TAG, "loadLatestServiceControlConfig: 本地无配置,沿用当前状态");
}
}
ControlCenterServiceBean latestBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class);
if (latestBean != null) {
mServiceControlBean = latestBean;
LogUtils.d(TAG, "loadLatestServiceControlConfig: 配置更新完成,启用状态=" + mServiceControlBean.isEnableService());
} else {
LogUtils.w(TAG, "loadLatestServiceControlConfig: 本地无配置,沿用当前状态");
}
}
/**
* 更新并持久化服务控制配置
*/
private void updateAndSaveServiceControlConfig(ControlCenterServiceBean newControlBean) {
if (newControlBean == null) {
LogUtils.e(TAG, "updateAndSaveServiceControlConfig: 配置为空,更新失败");
return;
}
LogUtils.d(TAG, "updateAndSaveServiceControlConfig: 更新配置,启用状态=" + newControlBean.isEnableService());
synchronized (mServiceLock) {
mServiceControlBean = newControlBean;
ControlCenterServiceBean.saveBean(this, mServiceControlBean);
}
ControlCenterServiceBean.saveBean(this, mServiceControlBean);
}
// ================================== 业务初始化与停止(按需加载,避免重复)=================================
/**
* 按需初始化核心业务
*/
private void initServiceBusinessIfNeed() {
LogUtils.d(TAG, "initServiceBusinessIfNeed: 校验业务初始化条件");
synchronized (mServiceLock) {
if (!mServiceControlBean.isEnableService() || mServiceHandler != null || !isServiceRunning || mIsDestroyed) {
LogUtils.w(TAG, "initServiceBusinessIfNeed: 无需初始化业务");
return;
}
// 初始化通知+配置+业务逻辑
initNotificationManager();
loadDefaultConfig();
initServiceBusinessLogic();
LogUtils.d(TAG, "initServiceBusinessIfNeed: 核心业务初始化完成");
}
}
/**
* 安全停止所有核心业务
*/
private void stopAllBusinessSafely() {
LogUtils.d(TAG, "stopAllBusinessSafely: 停止所有业务");
synchronized (mServiceLock) {
stopRemindThreadSafely();
destroyHandler();
stopForegroundService();
releaseNotificationResource();
mCurrentConfigBean = null;
mForegroundNotifyMsg = null;
}
}
/**
* 初始化通知管理工具类
*/
private void initNotificationManager() {
LogUtils.d(TAG, "initNotificationManager: 初始化通知工具");
if (mNotificationManager == null) {
mNotificationManager = new NotificationManagerUtils(this);
}
if (mForegroundNotifyMsg == null) {
mForegroundNotifyMsg = new NotificationMessage();
mForegroundNotifyMsg.setTitle("电池提醒服务运行中");
mForegroundNotifyMsg.setContent("后台持续监测电池状态");
mForegroundNotifyMsg.setRemindMSG("service_running");
}
}
// private void initNotificationManager() {
// LogUtils.d(TAG, "initNotificationManager: 初始化通知工具");
// if (mNotificationManager == null) {
// mNotificationManager = new NotificationManagerUtils(this);
// }
// if (mForegroundNotifyMsg == null) {
// mForegroundNotifyMsg = new NotificationMessage();
// mForegroundNotifyMsg.setTitle("电池提醒服务运行中");
// mForegroundNotifyMsg.setContent("后台持续监测电池状态");
// mForegroundNotifyMsg.setRemindMSG("service_running");
// }
// }
/**
* 加载默认应用配置
@@ -268,34 +251,30 @@ public class ControlCenterService extends Service {
*/
public void restartRemindThreadSafely() {
LogUtils.d(TAG, "restartRemindThreadSafely: 开始重启线程");
synchronized (mServiceLock) {
if (!isServiceRunning || mIsDestroyed || !mServiceControlBean.isEnableService()) {
LogUtils.e(TAG, "restartRemindThreadSafely: 服务状态异常,启动失败");
return;
}
// 停止旧线程
stopRemindThreadSafely();
if (mServiceHandler == null) {
LogUtils.e(TAG, "restartRemindThreadSafely: Handler为空启动失败");
return;
}
// 创建新线程实例
RemindThread.destroyInstance();
mRemindThread = RemindThread.getInstance(this, mServiceHandler);
syncConfigToRemindThread();
// 启动线程
if (mRemindThread != null && !mRemindThread.isAlive() && !mRemindThread.isThreadStarted()) {
try {
mRemindThread.start();
LogUtils.d(TAG, "restartRemindThreadSafely: 新线程启动成功ID=" + mRemindThread.getId());
} catch (IllegalThreadStateException e) {
LogUtils.e(TAG, "restartRemindThreadSafely: 线程重复启动异常", e);
mRemindThread = null;
}
} else {
LogUtils.w(TAG, "restartRemindThreadSafely: 线程状态异常,跳过启动");
}
}
// 停止旧线程
stopRemindThreadSafely();
if (mServiceHandler == null) {
// 创建新线程实例
RemindThread.destroyInstance();
mRemindThread = RemindThread.getInstance(this, mServiceHandler);
syncConfigToRemindThread();
// 启动线程
if (mRemindThread != null && !mRemindThread.isAlive() && !mRemindThread.isThreadStarted()) {
try {
mRemindThread.start();
LogUtils.d(TAG, "restartRemindThreadSafely: 新线程启动成功ID=" + mRemindThread.getId());
} catch (IllegalThreadStateException e) {
LogUtils.e(TAG, "restartRemindThreadSafely: 线程重复启动异常", e);
mRemindThread = null;
}
} else {
LogUtils.w(TAG, "restartRemindThreadSafely: 线程状态异常,跳过启动");
}
} else {
LogUtils.d(TAG, "mServiceHandler is null");
}
}
/**
@@ -335,44 +314,43 @@ public class ControlCenterService extends Service {
*/
private void syncConfigToRemindThread() {
LogUtils.d(TAG, "syncConfigToRemindThread: 同步配置");
synchronized (mServiceLock) {
if (mRemindThread == null || mCurrentConfigBean == null) {
LogUtils.e(TAG, "syncConfigToRemindThread: 线程或配置为空,同步失败");
return;
}
mRemindThread.setAppConfigBean(mCurrentConfigBean);
mRemindThread.setIsReminding(true);
}
if (mRemindThread == null || mCurrentConfigBean == null) {
LogUtils.e(TAG, "syncConfigToRemindThread: 线程或配置为空,同步失败");
return;
}
mRemindThread.setAppConfigBean(mCurrentConfigBean);
mRemindThread.setIsReminding(true);
}
// ================================== 外部指令处理接收Intent指令=================================
/**
* 处理外部发送的服务指令
*/
private void handleExternalCommand(Intent intent) {
LogUtils.d(TAG, "handleExternalCommand: 处理外部指令");
if (intent == null || TextUtils.isEmpty(intent.getAction())) {
LogUtils.e(TAG, "handleExternalCommand: Intent或Action为空");
return;
}
String action = intent.getAction();
if (ACTION_RESTART_REMIND_THREAD.equals(action)) {
synchronized (mServiceLock) {
if (mServiceControlBean.isEnableService()) {
AppConfigBean newConfig = (AppConfigBean) intent.getSerializableExtra(EXTRA_APP_CONFIG_BEAN);
if (newConfig != null) {
mCurrentConfigBean = newConfig;
LogUtils.d(TAG, "handleExternalCommand: 收到配置更新,重启线程");
restartRemindThreadSafely();
} else {
LogUtils.e(TAG, "handleExternalCommand: 配置为空,重启失败");
}
} else {
LogUtils.w(TAG, "handleExternalCommand: 服务已禁用,忽略指令");
}
}
}
}
// private void handleExternalCommand(Intent intent) {
// LogUtils.d(TAG, "handleExternalCommand: 处理外部指令");
// if (intent == null || TextUtils.isEmpty(intent.getAction())) {
// LogUtils.e(TAG, "handleExternalCommand: Intent或Action为空");
// return;
// }
// String action = intent.getAction();
// if (ACTION_RESTART_REMIND_THREAD.equals(action)) {
// synchronized (mServiceLock) {
// if (mServiceControlBean.isEnableService()) {
// AppConfigBean newConfig = (AppConfigBean) intent.getSerializableExtra(EXTRA_APP_CONFIG_BEAN);
// if (newConfig != null) {
// mCurrentConfigBean = newConfig;
// LogUtils.d(TAG, "handleExternalCommand: 收到配置更新,重启线程");
// restartRemindThreadSafely();
// } else {
// LogUtils.e(TAG, "handleExternalCommand: 配置为空,重启失败");
// }
// } else {
// LogUtils.w(TAG, "handleExternalCommand: 服务已禁用,忽略指令");
// }
// }
// }
// }
// ================================== 资源释放方法(防止内存泄漏)=================================
/**
@@ -432,11 +410,17 @@ public class ControlCenterService extends Service {
LogUtils.e(TAG, "startControlCenterService: Context为空");
return;
}
// 保存服务启动配置
ControlCenterServiceBean.saveBean(context, new ControlCenterServiceBean(true));
Intent intent = new Intent(context, ControlCenterService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
LogUtils.d(TAG, "startForegroundService 已调用");
} else {
context.startService(intent);
LogUtils.d(TAG, "startService 已调用");
}
}
@@ -449,6 +433,10 @@ public class ControlCenterService extends Service {
LogUtils.e(TAG, "stopControlCenterService: Context为空");
return;
}
// 保存服务启动配置
ControlCenterServiceBean.saveBean(context, new ControlCenterServiceBean(false));
Intent intent = new Intent(context, ControlCenterService.class);
context.stopService(intent);
}
@@ -456,20 +444,18 @@ public class ControlCenterService extends Service {
/**
* 更新服务控制配置并启停服务
*/
public static void updateServiceControlConfig(Context context, ControlCenterServiceBean controlBean) {
LogUtils.d(TAG, "updateServiceControlConfig: 更新控制配置,启用状态=" + controlBean.isEnableService());
if (context == null || controlBean == null) {
LogUtils.e(TAG, "updateServiceControlConfig: 参数为空");
return;
}
ControlCenterServiceBean.saveBean(context, controlBean);
if (controlBean.isEnableService()) {
stopControlCenterService(context);
startControlCenterService(context);
} else {
stopControlCenterService(context);
}
}
// public static void updateServiceControlConfig(Context context, ControlCenterServiceBean controlBean) {
// LogUtils.d(TAG, "updateServiceControlConfig: 更新控制配置,启用状态=" + controlBean.isEnableService());
// if (context == null || controlBean == null) {
// LogUtils.e(TAG, "updateServiceControlConfig: 参数为空");
// return;
// }
// if (controlBean.isEnableService()) {
// startControlCenterService(context);
// } else {
// stopControlCenterService(context);
// }
// }
/**
* 更新业务配置并触发线程重启
@@ -577,9 +563,7 @@ public class ControlCenterService extends Service {
// ================================== Getter/Setter 方法(线程安全)=================================
public RemindThread getRemindThread() {
synchronized (mServiceLock) {
return mRemindThread;
}
return mRemindThread;
}
public void setCurrentConfigBean(AppConfigBean configBean) {
@@ -588,47 +572,35 @@ public class ControlCenterService extends Service {
LogUtils.e(TAG, "setCurrentConfigBean: 配置为空");
return;
}
synchronized (mServiceLock) {
this.mCurrentConfigBean = configBean;
syncConfigToRemindThread();
}
this.mCurrentConfigBean = configBean;
syncConfigToRemindThread();
}
public void setServiceControlBean(ControlCenterServiceBean controlBean) {
LogUtils.d(TAG, "setServiceControlBean: 更新控制配置");
if (controlBean != null) {
updateAndSaveServiceControlConfig(controlBean);
}
}
// public void setServiceControlBean(ControlCenterServiceBean controlBean) {
// LogUtils.d(TAG, "setServiceControlBean: 更新控制配置");
// if (controlBean != null) {
// updateAndSaveServiceControlConfig(controlBean);
// }
// }
public ControlCenterServiceBean getServiceControlBean() {
synchronized (mServiceLock) {
return mServiceControlBean;
}
return mServiceControlBean;
}
public NotificationManagerUtils getNotificationManager() {
synchronized (mServiceLock) {
return mNotificationManager;
}
return mNotificationManager;
}
public NotificationMessage getForegroundNotifyMsg() {
synchronized (mServiceLock) {
return mForegroundNotifyMsg;
}
return mForegroundNotifyMsg;
}
public AppConfigBean getCurrentConfigBean() {
synchronized (mServiceLock) {
return mCurrentConfigBean;
}
return mCurrentConfigBean;
}
public boolean isDestroyed() {
synchronized (mServiceLock) {
return mIsDestroyed;
}
return mIsDestroyed;
}
}

View File

@@ -602,11 +602,12 @@ public class MainContentView {
break;
// 服务总开关(核心:持久化配置+触发 Activity 回调)
case CHANGE_TYPE_SERVICE_SWITCH:
// 1. 保存服务控制配置到本地
ControlCenterServiceBean serviceBean = ControlCenterServiceBean.loadBean(mContext, ControlCenterServiceBean.class);
if (serviceBean == null) serviceBean = new ControlCenterServiceBean(false);
serviceBean.setIsEnableService(mTempConfigData.newBooleanValue);
ControlCenterService.updateServiceControlConfig(mContext, serviceBean);
// 1. 设置服务启停
if (mTempConfigData.newBooleanValue) {
ControlCenterService.startControlCenterService(mContext);
} else {
ControlCenterService.stopControlCenterService(mContext);
}
// 2. 强制触发 Activity 回调,执行服务启停逻辑
mActionListener.onServiceSwitchChanged(mTempConfigData.newBooleanValue);
LogUtils.d(TAG, "confirmConfigChange: 服务开关确认,值=" + mTempConfigData.newBooleanValue + ",已持久化配置");