源码整理
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Fri Dec 19 19:04:54 GMT 2025
|
#Sat Dec 20 05:22:35 GMT 2025
|
||||||
stageCount=10
|
stageCount=10
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.14
|
baseVersion=15.14
|
||||||
publishVersion=15.14.9
|
publishVersion=15.14.9
|
||||||
buildCount=49
|
buildCount=51
|
||||||
baseBetaVersion=15.14.10
|
baseBetaVersion=15.14.10
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ import cc.winboll.studio.libaes.utils.DevelopUtils;
|
|||||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||||
import cc.winboll.studio.libaes.views.ADsBannerView;
|
import cc.winboll.studio.libaes.views.ADsBannerView;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
|
||||||
import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity;
|
import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.BatteryReportActivity;
|
import cc.winboll.studio.powerbell.activities.BatteryReportActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.SettingsActivity;
|
import cc.winboll.studio.powerbell.activities.SettingsActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.WinBoLLActivity;
|
import cc.winboll.studio.powerbell.activities.WinBoLLActivity;
|
||||||
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
|
||||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||||
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
||||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||||
@@ -38,9 +36,7 @@ import cc.winboll.studio.powerbell.utils.ServiceUtils;
|
|||||||
import cc.winboll.studio.powerbell.views.MainContentView;
|
import cc.winboll.studio.powerbell.views.MainContentView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* 应用核心主活动
|
||||||
* @Date 2025/12/19 20:26
|
|
||||||
* @Describe 应用核心主活动
|
|
||||||
* 功能:管理电池监控、背景设置、服务启停、权限申请等核心功能
|
* 功能:管理电池监控、背景设置、服务启停、权限申请等核心功能
|
||||||
* 适配:Java7 | API30 | 内存泄漏防护 | UI与服务状态实时同步
|
* 适配:Java7 | API30 | 内存泄漏防护 | UI与服务状态实时同步
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +46,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
|
|
||||||
// 请求码常量
|
// 请求码常量
|
||||||
private static final int REQUEST_READ_MEDIA_IMAGES = 1001;
|
private static final int REQUEST_READ_MEDIA_IMAGES = 1001;
|
||||||
// 延迟加载常量
|
// 延迟加载常量(非核心视图延迟加载时长)
|
||||||
private static final long DELAY_LOAD_NON_CRITICAL = 500L;
|
private static final long DELAY_LOAD_NON_CRITICAL = 500L;
|
||||||
// Handler消息标识(按业务优先级排序)
|
// Handler消息标识(按业务优先级排序)
|
||||||
public static final int MSG_RELOAD_APPCONFIG = 0;
|
public static final int MSG_RELOAD_APPCONFIG = 0;
|
||||||
@@ -92,7 +88,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
LogUtils.d(TAG, "onCreate: 页面启动,开始初始化流程");
|
LogUtils.d(TAG, "onCreate: 页面启动,开始初始化流程 | savedInstanceState=" + savedInstanceState);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// 优先初始化全局Handler,避免消息丢失
|
// 优先初始化全局Handler,避免消息丢失
|
||||||
@@ -126,6 +122,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
// 恢复广告
|
// 恢复广告
|
||||||
if (mADsBannerView != null) {
|
if (mADsBannerView != null) {
|
||||||
mADsBannerView.resumeADs(this);
|
mADsBannerView.resumeADs(this);
|
||||||
|
LogUtils.d(TAG, "onResume: 广告视图恢复展示");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,11 +140,13 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
if (mADsBannerView != null) {
|
if (mADsBannerView != null) {
|
||||||
mADsBannerView.releaseAdResources();
|
mADsBannerView.releaseAdResources();
|
||||||
mADsBannerView = null;
|
mADsBannerView = null;
|
||||||
|
LogUtils.d(TAG, "onDestroy: 广告资源已释放");
|
||||||
}
|
}
|
||||||
// 释放核心视图
|
// 释放核心视图
|
||||||
if (mMainContentView != null) {
|
if (mMainContentView != null) {
|
||||||
mMainContentView.releaseResources();
|
mMainContentView.releaseResources();
|
||||||
mMainContentView = null;
|
mMainContentView = null;
|
||||||
|
LogUtils.d(TAG, "onDestroy: 核心视图资源已释放");
|
||||||
}
|
}
|
||||||
// 销毁Handler,防止内存泄漏
|
// 销毁Handler,防止内存泄漏
|
||||||
if (sGlobalHandler != null) {
|
if (sGlobalHandler != null) {
|
||||||
@@ -159,6 +158,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
if (mFrameDrawable != null) {
|
if (mFrameDrawable != null) {
|
||||||
mFrameDrawable.setCallback(null);
|
mFrameDrawable.setCallback(null);
|
||||||
mFrameDrawable = null;
|
mFrameDrawable = null;
|
||||||
|
LogUtils.d(TAG, "onDestroy: 框架背景Drawable已释放");
|
||||||
}
|
}
|
||||||
// 置空所有引用,帮助GC回收
|
// 置空所有引用,帮助GC回收
|
||||||
sMainActivity = null;
|
sMainActivity = null;
|
||||||
@@ -176,7 +176,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
LogUtils.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);
|
LogUtils.d(TAG, "onActivityResult: requestCode=" + requestCode + " | resultCode=" + resultCode + " | data=" + data);
|
||||||
mPermissionUtils.handlePermissionRequest(this, requestCode, resultCode, data);
|
mPermissionUtils.handlePermissionRequest(this, requestCode, resultCode, data);
|
||||||
// 背景设置完成后重新加载
|
// 背景设置完成后重新加载
|
||||||
if (requestCode == REQUEST_READ_MEDIA_IMAGES && sGlobalHandler != null) {
|
if (requestCode == REQUEST_READ_MEDIA_IMAGES && sGlobalHandler != null) {
|
||||||
@@ -194,6 +194,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
if (App.isDebugging()) {
|
if (App.isDebugging()) {
|
||||||
DevelopUtils.inflateMenu(this, menu);
|
DevelopUtils.inflateMenu(this, menu);
|
||||||
getMenuInflater().inflate(R.menu.toolbar_unittest, mMenu);
|
getMenuInflater().inflate(R.menu.toolbar_unittest, mMenu);
|
||||||
|
LogUtils.d(TAG, "onCreateOptionsMenu: 调试模式,加载单元测试菜单");
|
||||||
}
|
}
|
||||||
getMenuInflater().inflate(R.menu.toolbar_main, mMenu);
|
getMenuInflater().inflate(R.menu.toolbar_main, mMenu);
|
||||||
return true;
|
return true;
|
||||||
@@ -201,7 +202,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
LogUtils.d(TAG, "onOptionsItemSelected: itemId=" + item.getItemId());
|
LogUtils.d(TAG, "onOptionsItemSelected: 菜单点击 | itemId=" + item.getItemId());
|
||||||
if (AESThemeUtil.onAppThemeItemSelected(this, item)) {
|
if (AESThemeUtil.onAppThemeItemSelected(this, item)) {
|
||||||
recreate();
|
recreate();
|
||||||
return true;
|
return true;
|
||||||
@@ -212,21 +213,27 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_settings:
|
case R.id.action_settings:
|
||||||
startActivity(new Intent(this, SettingsActivity.class));
|
startActivity(new Intent(this, SettingsActivity.class));
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转设置页面");
|
||||||
break;
|
break;
|
||||||
case R.id.action_battery_report:
|
case R.id.action_battery_report:
|
||||||
startActivity(new Intent(this, BatteryReportActivity.class));
|
startActivity(new Intent(this, BatteryReportActivity.class));
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转电池报告页面");
|
||||||
break;
|
break;
|
||||||
case R.id.action_clearrecord:
|
case R.id.action_clearrecord:
|
||||||
startActivity(new Intent(this, ClearRecordActivity.class));
|
startActivity(new Intent(this, ClearRecordActivity.class));
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转记录清理页面");
|
||||||
break;
|
break;
|
||||||
case R.id.action_changepicture:
|
case R.id.action_changepicture:
|
||||||
startActivityForResult(new Intent(this, BackgroundSettingsActivity.class), REQUEST_READ_MEDIA_IMAGES);
|
startActivityForResult(new Intent(this, BackgroundSettingsActivity.class), REQUEST_READ_MEDIA_IMAGES);
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转背景设置页面 | requestCode=" + REQUEST_READ_MEDIA_IMAGES);
|
||||||
break;
|
break;
|
||||||
case R.id.action_unittestactivity:
|
case R.id.action_unittestactivity:
|
||||||
startActivity(new Intent(this, MainUnitTestActivity.class));
|
startActivity(new Intent(this, MainUnitTestActivity.class));
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转单元测试页面");
|
||||||
break;
|
break;
|
||||||
case R.id.action_about:
|
case R.id.action_about:
|
||||||
startAboutActivity();
|
startAboutActivity();
|
||||||
|
LogUtils.d(TAG, "onOptionsItemSelected: 跳转关于页面");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
@@ -239,6 +246,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
super.setupToolbar();
|
super.setupToolbar();
|
||||||
if (getSupportActionBar() != null) {
|
if (getSupportActionBar() != null) {
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
|
LogUtils.d(TAG, "setupToolbar: 隐藏返回按钮");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,10 +275,10 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
// 校验Activity状态,避免销毁后操作UI
|
// 校验Activity状态,避免销毁后操作UI
|
||||||
if (sMainActivity == null || sMainActivity.isFinishing() || sMainActivity.isDestroyed()) {
|
if (sMainActivity == null || sMainActivity.isFinishing() || sMainActivity.isDestroyed()) {
|
||||||
LogUtils.w(TAG, "handleMessage: Activity已销毁,跳过消息 what=" + msg.what);
|
LogUtils.w(TAG, "handleMessage: Activity已销毁,跳过消息 | what=" + msg.what);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogUtils.d(TAG, "handleMessage: 处理消息 what=" + msg.what);
|
LogUtils.d(TAG, "handleMessage: 处理消息 | what=" + msg.what);
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_RELOAD_APPCONFIG:
|
case MSG_RELOAD_APPCONFIG:
|
||||||
sMainActivity.updateViewData();
|
sMainActivity.updateViewData();
|
||||||
@@ -278,6 +286,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
case MSG_CURRENTVALUEBATTERY:
|
case MSG_CURRENTVALUEBATTERY:
|
||||||
if (sMainActivity.mMainContentView != null) {
|
if (sMainActivity.mMainContentView != null) {
|
||||||
sMainActivity.mMainContentView.updateCurrentBattery(msg.arg1);
|
sMainActivity.mMainContentView.updateCurrentBattery(msg.arg1);
|
||||||
|
LogUtils.d(TAG, "handleMessage: 更新当前电量 | value=" + msg.arg1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_LOAD_BACKGROUND:
|
case MSG_LOAD_BACKGROUND:
|
||||||
@@ -307,6 +316,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
setSupportActionBar(mToolbar);
|
setSupportActionBar(mToolbar);
|
||||||
if (mToolbar != null) {
|
if (mToolbar != null) {
|
||||||
mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText);
|
mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText);
|
||||||
|
LogUtils.d(TAG, "initCriticalView: Toolbar样式设置完成");
|
||||||
}
|
}
|
||||||
mAdsViewStub = findViewById(R.id.stub_ads_banner);
|
mAdsViewStub = findViewById(R.id.stub_ads_banner);
|
||||||
}
|
}
|
||||||
@@ -316,7 +326,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
LogUtils.d(TAG, "initCoreUtilsAsync: 异步线程启动");
|
LogUtils.d(TAG, "initCoreUtilsAsync: 异步线程启动 | threadId=" + Thread.currentThread().getId());
|
||||||
mApplication = (App) getApplication();
|
mApplication = (App) getApplication();
|
||||||
mAppConfigUtils = AppConfigUtils.getInstance(getApplicationContext());
|
mAppConfigUtils = AppConfigUtils.getInstance(getApplicationContext());
|
||||||
mBgSourceUtils = BackgroundSourceUtils.getInstance(getActivity());
|
mBgSourceUtils = BackgroundSourceUtils.getInstance(getActivity());
|
||||||
@@ -332,6 +342,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
// 根据配置启停服务
|
// 根据配置启停服务
|
||||||
final boolean isServiceEnable = mServiceControlBean.isEnableService();
|
final boolean isServiceEnable = mServiceControlBean.isEnableService();
|
||||||
final boolean isServiceAlive = ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName());
|
final boolean isServiceAlive = ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName());
|
||||||
|
LogUtils.d(TAG, "initCoreUtilsAsync: 服务配置状态 | isServiceEnable=" + isServiceEnable + " | isServiceAlive=" + isServiceAlive);
|
||||||
if (isServiceEnable && !isServiceAlive) {
|
if (isServiceEnable && !isServiceAlive) {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -358,7 +369,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
LogUtils.w(TAG, "initCoreUtilsAsync: Activity已销毁,跳过UI更新");
|
LogUtils.w(TAG, "initCoreUtilsAsync: Activity已销毁,跳过UI更新");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 加载框架背景
|
// 加载框架背景(适配API23+)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
mFrameDrawable = getResources().getDrawable(R.drawable.bg_frame, getTheme());
|
mFrameDrawable = getResources().getDrawable(R.drawable.bg_frame, getTheme());
|
||||||
} else {
|
} else {
|
||||||
@@ -375,11 +386,12 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadNonCriticalViewDelayed() {
|
private void loadNonCriticalViewDelayed() {
|
||||||
LogUtils.d(TAG, "loadNonCriticalViewDelayed: 延迟加载非核心视图");
|
LogUtils.d(TAG, "loadNonCriticalViewDelayed: 延迟加载非核心视图 | 延迟时长=" + DELAY_LOAD_NON_CRITICAL + "ms");
|
||||||
new Handler().postDelayed(new Runnable() {
|
new Handler().postDelayed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (isFinishing() || isDestroyed()) {
|
if (isFinishing() || isDestroyed()) {
|
||||||
|
LogUtils.w(TAG, "loadNonCriticalViewDelayed: Activity已销毁,跳过广告加载");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loadAdsView();
|
loadAdsView();
|
||||||
@@ -391,7 +403,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
private void loadAdsView() {
|
private void loadAdsView() {
|
||||||
LogUtils.d(TAG, "loadAdsView: 加载广告视图");
|
LogUtils.d(TAG, "loadAdsView: 加载广告视图");
|
||||||
if (mAdsViewStub == null) {
|
if (mAdsViewStub == null) {
|
||||||
LogUtils.e(TAG, "loadAdsView: 广告ViewStub为空");
|
LogUtils.e(TAG, "loadAdsView: 广告ViewStub为空,加载失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mADsBannerView == null) {
|
if (mADsBannerView == null) {
|
||||||
@@ -408,6 +420,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mMainContentView.updateViewData(mFrameDrawable);
|
mMainContentView.updateViewData(mFrameDrawable);
|
||||||
|
LogUtils.d(TAG, "updateViewData: 视图数据更新完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadBackground() {
|
private void reloadBackground() {
|
||||||
@@ -419,6 +432,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean();
|
BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean();
|
||||||
if (currentBgBean != null) {
|
if (currentBgBean != null) {
|
||||||
mMainContentView.backgroundView.loadBackgroundBean(currentBgBean);
|
mMainContentView.backgroundView.loadBackgroundBean(currentBgBean);
|
||||||
|
LogUtils.d(TAG, "reloadBackground: 加载自定义背景成功");
|
||||||
} else {
|
} else {
|
||||||
mMainContentView.backgroundView.setBackgroundResource(R.drawable.default_background);
|
mMainContentView.backgroundView.setBackgroundResource(R.drawable.default_background);
|
||||||
LogUtils.w(TAG, "reloadBackground: 无自定义背景,使用默认背景");
|
LogUtils.w(TAG, "reloadBackground: 无自定义背景,使用默认背景");
|
||||||
@@ -434,6 +448,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean();
|
BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean();
|
||||||
if (currentBgBean != null) {
|
if (currentBgBean != null) {
|
||||||
mMainContentView.mainLayout.setBackgroundColor(currentBgBean.getPixelColor());
|
mMainContentView.mainLayout.setBackgroundColor(currentBgBean.getPixelColor());
|
||||||
|
LogUtils.d(TAG, "setMainLayoutBackgroundColor: 主布局背景色设置完成 | color=" + currentBgBean.getPixelColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,19 +463,21 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
mMainContentView.setServiceSwitchEnabled(false);
|
mMainContentView.setServiceSwitchEnabled(false);
|
||||||
mMainContentView.setServiceSwitchChecked(configEnabled);
|
mMainContentView.setServiceSwitchChecked(configEnabled);
|
||||||
mMainContentView.setServiceSwitchEnabled(true);
|
mMainContentView.setServiceSwitchEnabled(true);
|
||||||
|
LogUtils.d(TAG, "updateServiceSwitchUI: 服务开关UI状态更新完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== 服务与线程管理方法 ========================
|
// ======================== 服务与线程管理方法 ========================
|
||||||
private void toggleServiceEnableState(boolean isEnable) {
|
private void toggleServiceEnableState(boolean isEnable) {
|
||||||
LogUtils.d(TAG, "toggleServiceEnableState: 切换服务状态,目标状态=" + isEnable);
|
LogUtils.d(TAG, "toggleServiceEnableState: 切换服务状态 | 目标状态=" + isEnable);
|
||||||
if (mServiceControlBean == null) {
|
if (mServiceControlBean == null) {
|
||||||
LogUtils.e(TAG, "toggleServiceEnableState: 服务配置为空,切换失败");
|
LogUtils.e(TAG, "toggleServiceEnableState: 服务配置为空,切换失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mServiceControlBean.setIsEnableService(isEnable);
|
mServiceControlBean.setIsEnableService(isEnable);
|
||||||
ControlCenterServiceBean.saveBean(getApplicationContext(), mServiceControlBean);
|
ControlCenterServiceBean.saveBean(getApplicationContext(), mServiceControlBean);
|
||||||
|
LogUtils.d(TAG, "toggleServiceEnableState: 服务配置已保存");
|
||||||
|
|
||||||
// UI开关联动服务启停 + 线程销毁
|
// UI开关联动服务启停
|
||||||
if (isEnable) {
|
if (isEnable) {
|
||||||
// 开启:启动服务
|
// 开启:启动服务
|
||||||
if (!ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName())) {
|
if (!ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName())) {
|
||||||
@@ -488,8 +505,8 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
// ======================== 消息发送方法 ========================
|
// ======================== 消息发送方法 ========================
|
||||||
private void notifyServiceAppConfigChange() {
|
private void notifyServiceAppConfigChange() {
|
||||||
LogUtils.d(TAG, "notifyServiceAppConfigChange: 通知服务配置变更");
|
LogUtils.d(TAG, "notifyServiceAppConfigChange: 通知服务配置变更");
|
||||||
ControlCenterService.updateStatus(this);
|
ControlCenterService.updateStatus(this);
|
||||||
reloadAppConfig();
|
reloadAppConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== 静态工具方法 ========================
|
// ======================== 静态工具方法 ========================
|
||||||
@@ -497,18 +514,23 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
LogUtils.d(TAG, "reloadAppConfig: 发送配置重载消息");
|
LogUtils.d(TAG, "reloadAppConfig: 发送配置重载消息");
|
||||||
if (sGlobalHandler != null) {
|
if (sGlobalHandler != null) {
|
||||||
sGlobalHandler.sendEmptyMessage(MSG_RELOAD_APPCONFIG);
|
sGlobalHandler.sendEmptyMessage(MSG_RELOAD_APPCONFIG);
|
||||||
|
} else {
|
||||||
|
LogUtils.w(TAG, "reloadAppConfig: 全局Handler为空,消息发送失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendCurrentBatteryValueMessage(int value) {
|
public static void sendCurrentBatteryValueMessage(int value) {
|
||||||
LogUtils.d(TAG, "sendCurrentBatteryValueMessage: 发送当前电量消息,电量=" + value);
|
LogUtils.d(TAG, "sendCurrentBatteryValueMessage: 发送当前电量消息 | 电量=" + value);
|
||||||
if (sGlobalHandler != null) {
|
if (sGlobalHandler != null) {
|
||||||
Message msg = sGlobalHandler.obtainMessage(MSG_CURRENTVALUEBATTERY);
|
Message msg = sGlobalHandler.obtainMessage(MSG_CURRENTVALUEBATTERY);
|
||||||
msg.arg1 = value;
|
msg.arg1 = value;
|
||||||
sGlobalHandler.sendMessage(msg);
|
sGlobalHandler.sendMessage(msg);
|
||||||
|
} else {
|
||||||
|
LogUtils.w(TAG, "sendCurrentBatteryValueMessage: 全局Handler为空,消息发送失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ======================== 辅助工具方法 ========================
|
||||||
private APPInfo genDefaultAppInfo() {
|
private APPInfo genDefaultAppInfo() {
|
||||||
LogUtils.d(TAG, "genDefaultAppInfo: 生成默认应用信息");
|
LogUtils.d(TAG, "genDefaultAppInfo: 生成默认应用信息");
|
||||||
String branchName = "powerbell";
|
String branchName = "powerbell";
|
||||||
@@ -529,31 +551,31 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
|||||||
// ======================== MainContentView 事件回调 ========================
|
// ======================== MainContentView 事件回调 ========================
|
||||||
@Override
|
@Override
|
||||||
public void onChargeReminderSwitchChanged(boolean isChecked) {
|
public void onChargeReminderSwitchChanged(boolean isChecked) {
|
||||||
LogUtils.d(TAG, "onChargeReminderSwitchChanged: 充电提醒开关状态=" + isChecked);
|
LogUtils.d(TAG, "onChargeReminderSwitchChanged: 充电提醒开关状态变更 | isChecked=" + isChecked);
|
||||||
notifyServiceAppConfigChange();
|
notifyServiceAppConfigChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUsageReminderSwitchChanged(boolean isChecked) {
|
public void onUsageReminderSwitchChanged(boolean isChecked) {
|
||||||
LogUtils.d(TAG, "onUsageReminderSwitchChanged: 耗电提醒开关状态=" + isChecked);
|
LogUtils.d(TAG, "onUsageReminderSwitchChanged: 耗电提醒开关状态变更 | isChecked=" + isChecked);
|
||||||
notifyServiceAppConfigChange();
|
notifyServiceAppConfigChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceSwitchChanged(boolean isChecked) {
|
public void onServiceSwitchChanged(boolean isChecked) {
|
||||||
LogUtils.d(TAG, "onServiceSwitchChanged: 服务总开关状态=" + isChecked);
|
LogUtils.d(TAG, "onServiceSwitchChanged: 服务总开关状态变更 | isChecked=" + isChecked);
|
||||||
toggleServiceEnableState(isChecked);
|
toggleServiceEnableState(isChecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChargeReminderProgressChanged(int progress) {
|
public void onChargeReminderProgressChanged(int progress) {
|
||||||
LogUtils.d(TAG, "onChargeReminderProgressChanged: 充电提醒阈值=" + progress);
|
LogUtils.d(TAG, "onChargeReminderProgressChanged: 充电提醒阈值变更 | progress=" + progress);
|
||||||
notifyServiceAppConfigChange();
|
notifyServiceAppConfigChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUsageReminderProgressChanged(int progress) {
|
public void onUsageReminderProgressChanged(int progress) {
|
||||||
LogUtils.d(TAG, "onUsageReminderProgressChanged: 耗电提醒阈值=" + progress);
|
LogUtils.d(TAG, "onUsageReminderProgressChanged: 耗电提醒阈值变更 | progress=" + progress);
|
||||||
notifyServiceAppConfigChange();
|
notifyServiceAppConfigChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import cc.winboll.studio.powerbell.services.ControlCenterService;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* 服务通信Handler
|
||||||
* @Date 2025/12/19 20:17
|
|
||||||
* @Describe 服务通信Handler
|
|
||||||
* 功能:处理电量提醒消息,构建并发送标准化通知
|
* 功能:处理电量提醒消息,构建并发送标准化通知
|
||||||
* 特性:弱引用防泄漏、参数严格校验、通知格式统一
|
* 特性:弱引用防泄漏、参数严格校验、通知格式统一
|
||||||
* 适配:Java7 | API30 | 小米手机
|
* 适配:Java7 | API30 | 小米手机
|
||||||
@@ -33,7 +31,7 @@ public class ControlCenterServiceHandler extends Handler {
|
|||||||
|
|
||||||
// ================================== 构造方法(强制传入服务,初始化弱引用)=================================
|
// ================================== 构造方法(强制传入服务,初始化弱引用)=================================
|
||||||
public ControlCenterServiceHandler(ControlCenterService service) {
|
public ControlCenterServiceHandler(ControlCenterService service) {
|
||||||
LogUtils.d(TAG, "构造Handler | service=" + (service != null ? service.getClass().getSimpleName() : "null"));
|
LogUtils.d(TAG, "ControlCenterServiceHandler: 构造方法执行 | service=" + (service != null ? service.getClass().getSimpleName() : "null"));
|
||||||
this.mwrControlCenterService = new WeakReference<>(service);
|
this.mwrControlCenterService = new WeakReference<>(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +44,12 @@ public class ControlCenterServiceHandler extends Handler {
|
|||||||
int currentBattery = msg.arg1;
|
int currentBattery = msg.arg1;
|
||||||
boolean isCharging = msg.arg2 == 1;
|
boolean isCharging = msg.arg2 == 1;
|
||||||
|
|
||||||
LogUtils.d(TAG, "接收消息 | what=" + msg.what + " | type=" + remindType + " | battery=" + currentBattery + " | isCharging=" + isCharging);
|
LogUtils.d(TAG, "handleMessage: 接收消息 | what=" + msg.what + " | type=" + remindType + " | battery=" + currentBattery + " | isCharging=" + isCharging);
|
||||||
|
|
||||||
// 弱引用获取服务,避免内存泄漏
|
// 弱引用获取服务,避免内存泄漏
|
||||||
ControlCenterService service = mwrControlCenterService.get();
|
ControlCenterService service = mwrControlCenterService.get();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
LogUtils.e(TAG, "服务实例已回收,终止消息处理");
|
LogUtils.e(TAG, "handleMessage: 服务实例已被GC回收,终止消息处理");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +59,7 @@ public class ControlCenterServiceHandler extends Handler {
|
|||||||
handleRemindMessage(service, remindType, currentBattery, isCharging);
|
handleRemindMessage(service, remindType, currentBattery, isCharging);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogUtils.w(TAG, "未知消息类型 | what=" + msg.what);
|
LogUtils.w(TAG, "handleMessage: 未知消息类型,忽略处理 | what=" + msg.what);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,19 +73,19 @@ public class ControlCenterServiceHandler extends Handler {
|
|||||||
* @param isCharging 充电状态
|
* @param isCharging 充电状态
|
||||||
*/
|
*/
|
||||||
private void handleRemindMessage(ControlCenterService service, String remindType, int currentBattery, boolean isCharging) {
|
private void handleRemindMessage(ControlCenterService service, String remindType, int currentBattery, boolean isCharging) {
|
||||||
LogUtils.d(TAG, "处理提醒消息 | type=" + remindType + " | battery=" + currentBattery + " | isCharging=" + isCharging);
|
LogUtils.d(TAG, "handleRemindMessage: 开始处理提醒消息 | type=" + remindType + " | battery=" + currentBattery + " | isCharging=" + isCharging);
|
||||||
|
|
||||||
// 1. 前置校验:通知工具类+参数有效性
|
// 1. 前置校验:通知工具类+参数有效性
|
||||||
if (service.getNotificationManager() == null) {
|
if (service.getNotificationManager() == null) {
|
||||||
LogUtils.e(TAG, "通知管理工具类为空,无法发送提醒");
|
LogUtils.e(TAG, "handleRemindMessage: 通知管理工具类未初始化,无法发送提醒");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!REMIND_TYPE_CHARGE.equals(remindType) && !REMIND_TYPE_USAGE.equals(remindType)) {
|
if (!REMIND_TYPE_CHARGE.equals(remindType) && !REMIND_TYPE_USAGE.equals(remindType)) {
|
||||||
LogUtils.w(TAG, "无效提醒类型 | type=" + remindType);
|
LogUtils.w(TAG, "handleRemindMessage: 提醒类型无效,忽略 | type=" + remindType + " | 允许值:" + REMIND_TYPE_CHARGE + "/" + REMIND_TYPE_USAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentBattery < BATTERY_LEVEL_MIN || currentBattery > BATTERY_LEVEL_MAX) {
|
if (currentBattery < BATTERY_LEVEL_MIN || currentBattery > BATTERY_LEVEL_MAX) {
|
||||||
LogUtils.w(TAG, "无效电量值 | battery=" + currentBattery + ",需在0-100范围内");
|
LogUtils.w(TAG, "handleRemindMessage: 电量值超出范围,忽略 | battery=" + currentBattery + " | 允许范围:" + BATTERY_LEVEL_MIN + "-" + BATTERY_LEVEL_MAX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,11 +101,12 @@ public class ControlCenterServiceHandler extends Handler {
|
|||||||
remindMsg.setContent(String.format("(-) 当前电量%d%%,%s,已偏低建议及时充电,避免设备关机~", currentBattery, chargeStateDesc));
|
remindMsg.setContent(String.format("(-) 当前电量%d%%,%s,已偏低建议及时充电,避免设备关机~", currentBattery, chargeStateDesc));
|
||||||
remindMsg.setRemindMSG("usage_remind");
|
remindMsg.setRemindMSG("usage_remind");
|
||||||
}
|
}
|
||||||
LogUtils.d(TAG, "构建通知完成 | title=" + remindMsg.getTitle() + " | content=" + remindMsg.getContent());
|
LogUtils.d(TAG, "handleRemindMessage: 通知模型构建完成 | title=" + remindMsg.getTitle() + " | content=" + remindMsg.getContent());
|
||||||
|
|
||||||
// 3. 调用工具类发送通知
|
// 3. 直接调用通知工具类发送,不校验返回结果
|
||||||
|
LogUtils.d(TAG, "handleRemindMessage: 调用通知工具类发送提醒 | remindMSG=" + remindMsg.getRemindMSG());
|
||||||
service.getNotificationManager().showRemindNotification(service, remindMsg);
|
service.getNotificationManager().showRemindNotification(service, remindMsg);
|
||||||
LogUtils.d(TAG, "提醒通知发送成功");
|
LogUtils.d(TAG, "handleRemindMessage: 提醒通知发送流程执行完毕");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,101 +5,167 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.powerbell.App;
|
import cc.winboll.studio.powerbell.App;
|
||||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
|
||||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||||
import cc.winboll.studio.powerbell.utils.ServiceUtils;
|
import cc.winboll.studio.powerbell.utils.ServiceUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电池提醒核心服务进程守护类
|
||||||
|
* 功能:监听主服务 {@link ControlCenterService} 存活状态,异常断开时自动重启并绑定
|
||||||
|
* 适配:Java7 | API30 | 前台服务启动规则 | 服务绑定稳定性保障
|
||||||
|
*/
|
||||||
public class AssistantService extends Service {
|
public class AssistantService extends Service {
|
||||||
private final static String TAG = "AssistantService";
|
// ================================== 静态常量区(置顶归类,消除魔法值)=================================
|
||||||
|
private static final String TAG = "AssistantService";
|
||||||
|
// 服务返回策略常量(统一定义,避免魔法值)
|
||||||
|
private static final int SERVICE_RETURN_STICKY = START_STICKY;
|
||||||
|
|
||||||
//MyBinder mMyBinder;
|
// ================================== 成员变量区(按功能分层,volatile保证多线程可见性)=================================
|
||||||
MyServiceConnection mMyServiceConnection;
|
private MyServiceConnection mMyServiceConnection;
|
||||||
volatile boolean mIsThreadAlive;
|
private volatile boolean mIsThreadAlive;
|
||||||
AppConfigUtils mAppConfigUtils;
|
private AppConfigUtils mAppConfigUtils;
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
//return mMyBinder;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// ================================== 服务生命周期方法(按执行顺序排列:onCreate→onStartCommand→onBind→onDestroy)=================================
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
//LogUtils.d(TAG, "onCreate");
|
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mAppConfigUtils = App.getAppConfigUtils(this);
|
LogUtils.d(TAG, "onCreate: 守护服务启动 | 进程ID=" + android.os.Process.myPid());
|
||||||
|
|
||||||
//mMyBinder = new MyBinder();
|
// 初始化配置工具类,添加空指针防护
|
||||||
|
mAppConfigUtils = App.getAppConfigUtils(this);
|
||||||
|
if (mAppConfigUtils == null) {
|
||||||
|
LogUtils.e(TAG, "onCreate: AppConfigUtils初始化失败,守护服务无法工作");
|
||||||
|
stopSelf();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化服务连接对象
|
||||||
if (mMyServiceConnection == null) {
|
if (mMyServiceConnection == null) {
|
||||||
mMyServiceConnection = new MyServiceConnection();
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
|
LogUtils.d(TAG, "onCreate: ServiceConnection初始化完成");
|
||||||
}
|
}
|
||||||
// 设置运行参数
|
|
||||||
|
// 初始化运行状态,执行核心守护逻辑
|
||||||
mIsThreadAlive = false;
|
mIsThreadAlive = false;
|
||||||
run();
|
run();
|
||||||
|
LogUtils.d(TAG, "onCreate: 守护服务初始化完成 | 服务启用状态=" + mAppConfigUtils.isServiceEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
//LogUtils.d(TAG, "call onStartCommand(...)");
|
LogUtils.d(TAG, "onStartCommand: 守护服务触发重启 | intent=" + intent + " | flags=" + flags + " | startId=" + startId);
|
||||||
|
// 配置工具类为空时,直接返回非粘性策略
|
||||||
|
if (mAppConfigUtils == null) {
|
||||||
|
LogUtils.e(TAG, "onStartCommand: AppConfigUtils未初始化,终止服务");
|
||||||
|
stopSelf();
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
return START_STICKY;
|
int returnFlag = mAppConfigUtils.isServiceEnabled() ? SERVICE_RETURN_STICKY : super.onStartCommand(intent, flags, startId);
|
||||||
|
LogUtils.d(TAG, "onStartCommand: 处理完成 | 返回策略=" + (returnFlag == SERVICE_RETURN_STICKY ? "START_STICKY" : "DEFAULT"));
|
||||||
|
return returnFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*class MyBinder extends IMyAidlInterface.Stub {
|
@Override
|
||||||
@Override
|
public IBinder onBind(Intent intent) {
|
||||||
public String getServiceName() {
|
LogUtils.d(TAG, "onBind: 服务绑定请求 | intent=" + intent);
|
||||||
return AssistantService.class.getSimpleName();
|
return null;
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
//LogUtils.d(TAG, "onDestroy");
|
|
||||||
mIsThreadAlive = false;
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
LogUtils.d(TAG, "onDestroy: 守护服务销毁流程启动");
|
||||||
|
|
||||||
|
// 重置运行状态,终止守护逻辑
|
||||||
|
mIsThreadAlive = false;
|
||||||
|
|
||||||
|
// 解绑主服务,添加异常捕获防止重复解绑崩溃
|
||||||
|
if (mMyServiceConnection != null) {
|
||||||
|
try {
|
||||||
|
unbindService(mMyServiceConnection);
|
||||||
|
LogUtils.d(TAG, "onDestroy: 已成功解绑ControlCenterService");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
LogUtils.w(TAG, "onDestroy: 解绑服务失败,服务未绑定 | " + e.getMessage());
|
||||||
|
}
|
||||||
|
mMyServiceConnection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 置空工具类引用,帮助GC回收
|
||||||
|
mAppConfigUtils = null;
|
||||||
|
LogUtils.d(TAG, "onDestroy: 守护服务销毁完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 运行服务内容
|
// ================================== 核心业务逻辑(守护主服务存活)=================================
|
||||||
//
|
/**
|
||||||
void run() {
|
* 执行守护逻辑:检查主服务状态,按需唤醒并绑定
|
||||||
//LogUtils.d(TAG, "run");
|
* 前置条件:mAppConfigUtils 必须初始化完成
|
||||||
|
*/
|
||||||
|
private void run() {
|
||||||
|
LogUtils.d(TAG, "run: 执行守护逻辑 | 配置启用=" + mAppConfigUtils.isServiceEnabled() + " | 线程存活=" + mIsThreadAlive);
|
||||||
if (mAppConfigUtils.isServiceEnabled()) {
|
if (mAppConfigUtils.isServiceEnabled()) {
|
||||||
if (mIsThreadAlive == false) {
|
if (!mIsThreadAlive) {
|
||||||
// 设置运行状态
|
|
||||||
mIsThreadAlive = true;
|
mIsThreadAlive = true;
|
||||||
// 唤醒和绑定主进程
|
|
||||||
wakeupAndBindMain();
|
wakeupAndBindMain();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LogUtils.d(TAG, "run: 服务未启用,跳过守护逻辑");
|
||||||
|
// 服务未启用时,重置线程状态
|
||||||
|
mIsThreadAlive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 唤醒和绑定主进程
|
/**
|
||||||
//
|
* 唤醒主服务并建立绑定,确保主服务持续运行
|
||||||
void wakeupAndBindMain() {
|
* 适配 API26+ 前台服务启动规则,避免系统限制导致启动失败
|
||||||
if (ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName()) == false) {
|
*/
|
||||||
//LogUtils.d(TAG, "wakeupAndBindMain() Wakeup... ControlCenterService");
|
private void wakeupAndBindMain() {
|
||||||
startForegroundService(new Intent(AssistantService.this, ControlCenterService.class));
|
// 检查主服务存活状态
|
||||||
|
boolean isMainServiceAlive = ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName());
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindMain: 主服务存活状态=" + isMainServiceAlive);
|
||||||
|
|
||||||
|
// 主服务未存活时,按需启动(区分API版本)
|
||||||
|
if (!isMainServiceAlive) {
|
||||||
|
Intent mainServiceIntent = new Intent(AssistantService.this, ControlCenterService.class);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
startForegroundService(mainServiceIntent);
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindMain: API26+ 以前台服务方式启动主服务");
|
||||||
|
} else {
|
||||||
|
startService(mainServiceIntent);
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindMain: 以普通服务方式启动主服务");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//LogUtils.d(TAG, "wakeupAndBindMain() Bind... ControlCenterService");
|
|
||||||
bindService(new Intent(AssistantService.this, ControlCenterService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
// 绑定主服务,监听连接状态,添加结果日志
|
||||||
|
Intent bindIntent = new Intent(AssistantService.this, ControlCenterService.class);
|
||||||
|
boolean bindResult = bindService(bindIntent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindMain: 绑定主服务结果=" + bindResult + " | 绑定标记=BIND_IMPORTANT");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 主进程与守护进程连接时需要用到此类
|
// ================================== 内部类(服务连接状态监听)=================================
|
||||||
//
|
/**
|
||||||
class MyServiceConnection implements ServiceConnection {
|
* 服务连接状态监听器
|
||||||
|
* 主服务连接成功时记录状态,断开时自动重连
|
||||||
|
*/
|
||||||
|
private class MyServiceConnection implements ServiceConnection {
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
//LogUtils.d(TAG, "call onServiceConnected(...)");
|
LogUtils.d(TAG, "onServiceConnected: 主服务连接成功 | 组件名=" + name.getClassName() + " | Binder=" + service);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
//LogUtils.d(TAG, "call onServiceDisconnected(...)");
|
LogUtils.d(TAG, "onServiceDisconnected: 主服务连接断开 | 组件名=" + name.getClassName());
|
||||||
if (mAppConfigUtils.isServiceEnabled()) {
|
// 主服务断开且配置启用时,重新唤醒绑定
|
||||||
|
if (mAppConfigUtils != null && mAppConfigUtils.isServiceEnabled()) {
|
||||||
|
LogUtils.d(TAG, "onServiceDisconnected: 尝试重新唤醒并绑定主服务");
|
||||||
wakeupAndBindMain();
|
wakeupAndBindMain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,22 +9,19 @@ import android.os.Build;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import java.util.List;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
|
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
|
||||||
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
||||||
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
||||||
import cc.winboll.studio.powerbell.models.NotificationMessage;
|
import cc.winboll.studio.powerbell.models.NotificationMessage;
|
||||||
|
import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver;
|
||||||
import cc.winboll.studio.powerbell.threads.RemindThread;
|
import cc.winboll.studio.powerbell.threads.RemindThread;
|
||||||
import cc.winboll.studio.powerbell.utils.NotificationManagerUtils;
|
import cc.winboll.studio.powerbell.utils.NotificationManagerUtils;
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* 电池提醒核心服务
|
||||||
* @Date 2025/12/19 20:21
|
|
||||||
* @Describe 电池提醒核心服务
|
|
||||||
* 功能:管理前台服务生命周期、控制提醒线程启停、处理配置更新
|
* 功能:管理前台服务生命周期、控制提醒线程启停、处理配置更新
|
||||||
* 适配:Java7 | API30 | 前台服务超时防护 | 电池优化忽略引导
|
* 适配:Java7 | API30 | 前台服务超时防护 | 电池优化忽略引导
|
||||||
*/
|
*/
|
||||||
@@ -32,10 +29,6 @@ public class ControlCenterService extends Service {
|
|||||||
// ================================== 静态常量区(置顶归类,消除魔法值)=================================
|
// ================================== 静态常量区(置顶归类,消除魔法值)=================================
|
||||||
public static final String TAG = "ControlCenterService";
|
public static final String TAG = "ControlCenterService";
|
||||||
|
|
||||||
// 服务指令Action常量(带包名前缀防冲突)
|
|
||||||
// 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";
|
|
||||||
|
|
||||||
// 超时/阈值常量
|
// 超时/阈值常量
|
||||||
private static final long THREAD_STOP_TIMEOUT = 1000L;
|
private static final long THREAD_STOP_TIMEOUT = 1000L;
|
||||||
// 服务状态标记常量
|
// 服务状态标记常量
|
||||||
@@ -315,8 +308,7 @@ public class ControlCenterService extends Service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 外部更新配置并触发线程重启
|
* 外部更新配置并触发线程重启
|
||||||
* @param context 上下文
|
* @param context 上下文
|
||||||
* @param configBean 新配置
|
|
||||||
*/
|
*/
|
||||||
public static void updateStatus(Context context) {
|
public static void updateStatus(Context context) {
|
||||||
LogUtils.d(TAG, "updateStatus: 外部更新配置 | context=" + context);
|
LogUtils.d(TAG, "updateStatus: 外部更新配置 | context=" + context);
|
||||||
@@ -329,6 +321,7 @@ public class ControlCenterService extends Service {
|
|||||||
intent.setAction(ControlCenterServiceReceiver.ACTION_APPCONFIG_CHANGED);
|
intent.setAction(ControlCenterServiceReceiver.ACTION_APPCONFIG_CHANGED);
|
||||||
intent.setPackage(context.getPackageName());
|
intent.setPackage(context.getPackageName());
|
||||||
context.sendBroadcast(intent);
|
context.sendBroadcast(intent);
|
||||||
|
LogUtils.d(TAG, "updateStatus: 配置更新广播已发送 | action=" + ControlCenterServiceReceiver.ACTION_APPCONFIG_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -357,7 +350,7 @@ public class ControlCenterService extends Service {
|
|||||||
intent.setData(Uri.parse("package:" + packageName));
|
intent.setData(Uri.parse("package:" + packageName));
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 已跳转至系统设置页");
|
LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 已跳转至系统设置页 | package=" + packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +361,7 @@ public class ControlCenterService extends Service {
|
|||||||
* @return true=运行中 false=未运行
|
* @return true=运行中 false=未运行
|
||||||
*/
|
*/
|
||||||
private static boolean isServiceRunning(Context context, Class<?> serviceClass) {
|
private static boolean isServiceRunning(Context context, Class<?> serviceClass) {
|
||||||
LogUtils.d(TAG, "isServiceRunning: 检查服务状态 | context=" + context + " | service=" + serviceClass);
|
LogUtils.d(TAG, "isServiceRunning: 检查服务状态 | context=" + context + " | service=" + serviceClass.getName());
|
||||||
if (context == null || serviceClass == null) {
|
if (context == null || serviceClass == null) {
|
||||||
LogUtils.e(TAG, "isServiceRunning: 参数为空");
|
LogUtils.e(TAG, "isServiceRunning: 参数为空");
|
||||||
return false;
|
return false;
|
||||||
@@ -444,9 +437,9 @@ public class ControlCenterService extends Service {
|
|||||||
if (latestConfig != null && mServiceHandler != null) {
|
if (latestConfig != null && mServiceHandler != null) {
|
||||||
mCurrentConfigBean = latestConfig;
|
mCurrentConfigBean = latestConfig;
|
||||||
RemindThread.startRemindThread(this, mServiceHandler, latestConfig);
|
RemindThread.startRemindThread(this, mServiceHandler, latestConfig);
|
||||||
LogUtils.d(TAG, "notifyAppConfigUpdate: 配置已同步到线程");
|
LogUtils.d(TAG, "notifyAppConfigUpdate: 配置已同步到提醒线程");
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e(TAG, "notifyAppConfigUpdate: 参数为空,同步失败");
|
LogUtils.e(TAG, "notifyAppConfigUpdate: 参数为空,同步失败 | latestConfig=" + latestConfig + " | mServiceHandler=" + mServiceHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user