diff --git a/powerbell/build.properties b/powerbell/build.properties index c2edd88..32c1149 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed Dec 24 09:10:57 GMT 2025 +#Wed Dec 24 11:16:45 GMT 2025 stageCount=29 libraryProject= baseVersion=15.14 publishVersion=15.14.28 -buildCount=57 +buildCount=82 baseBetaVersion=15.14.29 diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java index 59e1768..3da4274 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java @@ -15,6 +15,7 @@ import cc.winboll.studio.powerbell.views.MemoryCachedBackgroundView; /** * 应用全局入口类(适配Android API 30,基于Java 7编写) * 核心策略:极致强制缓存 - 无论内存紧张程度,永不自动清理任何缓存(Bitmap/视图控件/路径记录) + * @Author 豆包&ZhanGSKen */ public class App extends GlobalApplication { // ===================== 常量定义区(按功能分类排序) ===================== @@ -35,7 +36,7 @@ public class App extends GlobalApplication { // ===================== 静态属性区(按工具类优先级排序) ===================== // 数据配置工具 - private static AppConfigUtils sAppConfigUtils; + public static AppConfigUtils sAppConfigUtils; private static AppCacheUtils sAppCacheUtils; // 全局Bitmap缓存工具(极致强制保持:一旦初始化,永不销毁) @@ -56,7 +57,8 @@ public class App extends GlobalApplication { * 获取应用配置工具实例 */ public static AppConfigUtils getAppConfigUtils(Context context) { - LogUtils.d(TAG, "getAppConfigUtils() 调用,传入Context类型:" + (context != null ? context.getClass().getSimpleName() : "null")); + LogUtils.d(TAG, String.format("getAppConfigUtils() 调用 | 传入Context类型=%s", + context != null ? context.getClass().getSimpleName() : "null")); if (sAppConfigUtils == null) { sAppConfigUtils = AppConfigUtils.getInstance(context); LogUtils.d(TAG, "getAppConfigUtils():AppConfigUtils实例已初始化"); @@ -68,7 +70,8 @@ public class App extends GlobalApplication { * 获取应用缓存工具实例 */ public static AppCacheUtils getAppCacheUtils(Context context) { - LogUtils.d(TAG, "getAppCacheUtils() 调用,传入Context类型:" + (context != null ? context.getClass().getSimpleName() : "null")); + LogUtils.d(TAG, String.format("getAppCacheUtils() 调用 | 传入Context类型=%s", + context != null ? context.getClass().getSimpleName() : "null")); if (sAppCacheUtils == null) { sAppCacheUtils = AppCacheUtils.getInstance(context); LogUtils.d(TAG, "getAppCacheUtils():AppCacheUtils实例已初始化"); @@ -95,18 +98,18 @@ public class App extends GlobalApplication { * 极致强制缓存策略下,仅提供手动清理入口,永不自动调用 */ public static void manualClearAllCache() { - LogUtils.w(TAG, CACHE_PROTECT_TAG + " 手动清理缓存调用(极致强制缓存策略下,需谨慎使用)"); + LogUtils.w(TAG, String.format("%s 手动清理缓存调用(极致强制缓存策略下,需谨慎使用)", CACHE_PROTECT_TAG)); // 清理Bitmap缓存 if (sBitmapCacheUtils != null) { sBitmapCacheUtils.clearAllCache(); - LogUtils.d(TAG, CACHE_PROTECT_TAG + " Bitmap缓存已手动清理"); + LogUtils.d(TAG, String.format("%s Bitmap缓存已手动清理", CACHE_PROTECT_TAG)); } // 清理视图控件缓存(仅清除静态引用,不销毁实例) if (sMemoryCachedBackgroundView != null) { - LogUtils.d(TAG, CACHE_PROTECT_TAG + " 视图控件缓存实例保持,仅清除静态引用"); + LogUtils.d(TAG, String.format("%s 视图控件缓存实例保持,仅清除静态引用", CACHE_PROTECT_TAG)); sMemoryCachedBackgroundView = null; } - LogUtils.w(TAG, CACHE_PROTECT_TAG + " 手动清理缓存完成(部分缓存实例仍可能保留在内存中)"); + LogUtils.w(TAG, String.format("%s 手动清理缓存完成(部分缓存实例仍可能保留在内存中)", CACHE_PROTECT_TAG)); } // ===================== 生命周期方法区(按执行顺序排序) ===================== @@ -117,7 +120,7 @@ public class App extends GlobalApplication { // 初始化调试模式 setIsDebugging(BuildConfig.DEBUG); - LogUtils.d(TAG, "onCreate() 调试模式:" + BuildConfig.DEBUG); + LogUtils.d(TAG, String.format("onCreate() 调试模式=%b", BuildConfig.DEBUG)); // 初始化基础工具 initBaseTools(); @@ -143,7 +146,7 @@ public class App extends GlobalApplication { releaseReceiver(); // 核心修改:应用终止时也不清理缓存,保持静态实例 - LogUtils.w(TAG, CACHE_PROTECT_TAG + " 应用终止,极致强制缓存策略生效,不清理任何缓存"); + LogUtils.w(TAG, String.format("%s 应用终止,极致强制缓存策略生效,不清理任何缓存", CACHE_PROTECT_TAG)); LogUtils.d(TAG, "onTerminate() 非缓存资源释放完成,缓存实例保持"); } @@ -152,7 +155,8 @@ public class App extends GlobalApplication { public void onTrimMemory(int level) { super.onTrimMemory(level); // 极致强制缓存:禁止任何缓存清理操作,仅记录日志 - LogUtils.w(TAG, CACHE_PROTECT_TAG + " onTrimMemory() 调用,内存等级level:" + level + ",极致强制保持所有缓存"); + LogUtils.w(TAG, String.format("%s onTrimMemory() 调用 | 内存等级level=%d | 极致强制保持所有缓存", + CACHE_PROTECT_TAG, level)); // 记录详细缓存状态,不执行任何清理 logDetailedCacheStatus(); } @@ -161,7 +165,7 @@ public class App extends GlobalApplication { public void onLowMemory() { super.onLowMemory(); // 极致强制缓存:低内存时也不清理任何缓存 - LogUtils.w(TAG, CACHE_PROTECT_TAG + " onLowMemory() 调用,极致强制保持所有缓存"); + LogUtils.w(TAG, String.format("%s onLowMemory() 调用 | 极致强制保持所有缓存", CACHE_PROTECT_TAG)); // 记录详细缓存状态,不执行任何清理 logDetailedCacheStatus(); } @@ -244,21 +248,22 @@ public class App extends GlobalApplication { LogUtils.d(TAG, "logDetailedCacheStatus() 开始记录详细缓存状态"); // Bitmap缓存状态 if (sBitmapCacheUtils != null) { - LogUtils.d(TAG, CACHE_PROTECT_TAG + " Bitmap缓存工具实例有效(极致强制保持)"); + LogUtils.d(TAG, String.format("%s Bitmap缓存工具实例有效(极致强制保持)", CACHE_PROTECT_TAG)); // 假设BitmapCacheUtils有获取缓存数量的方法 try { int cacheCount = sBitmapCacheUtils.getCacheCount(); - LogUtils.d(TAG, CACHE_PROTECT_TAG + " Bitmap缓存数量:" + cacheCount); + LogUtils.d(TAG, String.format("%s Bitmap缓存数量=%d", CACHE_PROTECT_TAG, cacheCount)); } catch (Exception e) { - LogUtils.d(TAG, CACHE_PROTECT_TAG + " Bitmap缓存数量获取失败(不影响缓存),异常信息:" + e.getMessage()); + LogUtils.d(TAG, String.format("%s Bitmap缓存数量获取失败(不影响缓存)| 异常信息=%s", + CACHE_PROTECT_TAG, e.getMessage())); } } // 视图控件缓存状态 if (sMemoryCachedBackgroundView != null) { - LogUtils.d(TAG, CACHE_PROTECT_TAG + " 视图控件缓存工具实例有效(极致强制保持)"); + LogUtils.d(TAG, String.format("%s 视图控件缓存工具实例有效(极致强制保持)", CACHE_PROTECT_TAG)); // 记录视图实例总数 int viewInstanceCount = MemoryCachedBackgroundView.getInstanceCount(); - LogUtils.d(TAG, CACHE_PROTECT_TAG + " 视图控件实例总数:" + viewInstanceCount); + LogUtils.d(TAG, String.format("%s 视图控件实例总数=%d", CACHE_PROTECT_TAG, viewInstanceCount)); } LogUtils.d(TAG, "logDetailedCacheStatus() 详细缓存状态记录完成,所有缓存均极致强制保持"); } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java index a2d8c02..465e7a4 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java @@ -35,11 +35,13 @@ import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; import cc.winboll.studio.powerbell.utils.PermissionUtils; import cc.winboll.studio.powerbell.utils.ServiceUtils; import cc.winboll.studio.powerbell.views.MainContentView; +import cc.winboll.studio.libappbase.ToastUtils; /** * 应用核心主活动 * 功能:管理电池监控、背景设置、服务启停、权限申请等核心功能 * 适配:Java7 | API30 | 内存泄漏防护 | UI与服务状态实时同步 + * @Author 豆包&ZhanGSKen */ public class MainActivity extends WinBoLLActivity implements MainContentView.OnViewActionListener { @@ -87,7 +89,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - LogUtils.d(TAG, "onCreate() | savedInstanceState=" + savedInstanceState); + LogUtils.d(TAG, String.format("onCreate() | savedInstanceState=%s", savedInstanceState)); initGlobalHandler(); setContentView(R.layout.activity_main); @@ -101,7 +103,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - LogUtils.d(TAG, "onPostCreate() | savedInstanceState=" + savedInstanceState); + LogUtils.d(TAG, String.format("onPostCreate() | savedInstanceState=%s", savedInstanceState)); mPermissionUtils.startPermissionRequest(this); LogUtils.d(TAG, "onPostCreate: 发起权限申请"); } @@ -110,9 +112,10 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV protected void onResume() { super.onResume(); LogUtils.d(TAG, "onResume()"); - + if (mADsBannerView != null) { mADsBannerView.resumeADs(this); + LogUtils.d(TAG, "onResume: 广告视图已恢复"); } } @@ -131,21 +134,25 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV if (mADsBannerView != null) { mADsBannerView.releaseAdResources(); mADsBannerView = null; + LogUtils.d(TAG, "onDestroy: 广告资源已释放"); } // 释放核心视图 if (mMainContentView != null) { mMainContentView.releaseResources(); mMainContentView = null; + LogUtils.d(TAG, "onDestroy: 核心视图资源已释放"); } // 销毁Handler,防止内存泄漏 if (sGlobalHandler != null) { sGlobalHandler.removeCallbacksAndMessages(null); sGlobalHandler = null; + LogUtils.d(TAG, "onDestroy: 全局Handler已销毁"); } // 释放Drawable if (mFrameDrawable != null) { mFrameDrawable.setCallback(null); mFrameDrawable = null; + LogUtils.d(TAG, "onDestroy: 框架Drawable已释放"); } // 置空所有引用 sMainActivity = null; @@ -162,22 +169,25 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - LogUtils.d(TAG, "onActivityResult() | requestCode=" + requestCode + " | resultCode=" + resultCode + " | data=" + data); + LogUtils.d(TAG, String.format("onActivityResult() | requestCode=%d | resultCode=%d | data=%s", + requestCode, resultCode, data)); mPermissionUtils.handlePermissionRequest(this, requestCode, resultCode, data); if (requestCode == REQUEST_BACKGROUND_SETTINGS_ACTIVITY && sGlobalHandler != null) { sGlobalHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND); + LogUtils.d(TAG, "onActivityResult: 发送背景加载消息"); } } // ======================== 菜单与导航方法 ======================== @Override public boolean onCreateOptionsMenu(Menu menu) { - LogUtils.d(TAG, "onCreateOptionsMenu() | menu=" + menu); + LogUtils.d(TAG, String.format("onCreateOptionsMenu() | menu=%s", menu)); mMenu = menu; AESThemeUtil.inflateMenu(this, menu); if (App.isDebugging()) { DevelopUtils.inflateMenu(this, menu); getMenuInflater().inflate(R.menu.toolbar_unittest, mMenu); + LogUtils.d(TAG, "onCreateOptionsMenu: 已加载测试菜单"); } getMenuInflater().inflate(R.menu.toolbar_main, mMenu); return true; @@ -185,7 +195,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override public boolean onOptionsItemSelected(MenuItem item) { - LogUtils.d(TAG, "onOptionsItemSelected() | itemId=" + item.getItemId()); + LogUtils.d(TAG, String.format("onOptionsItemSelected() | itemId=%d", item.getItemId())); if (AESThemeUtil.onAppThemeItemSelected(this, item)) { recreate(); return true; @@ -209,7 +219,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV case R.id.action_unittestactivity: startActivity(new Intent(this, MainUnitTestActivity.class)); break; - case R.id.action_unittest2activity: + case R.id.action_unittest2activity: startActivity(new Intent(this, MainUnitTest2Activity.class)); break; case R.id.action_about: @@ -227,6 +237,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV LogUtils.d(TAG, "setupToolbar()"); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(false); + LogUtils.d(TAG, "setupToolbar: 已隐藏返回按钮"); } } @@ -234,11 +245,12 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV public void onBackPressed() { LogUtils.d(TAG, "onBackPressed()"); moveTaskToBack(true); + LogUtils.d(TAG, "onBackPressed: 应用已退至后台"); } @Override public boolean dispatchKeyEvent(KeyEvent event) { - LogUtils.d(TAG, "dispatchKeyEvent() | event=" + event); + LogUtils.d(TAG, String.format("dispatchKeyEvent() | event=%s", event)); return super.dispatchKeyEvent(event); } @@ -246,6 +258,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV private void initPermissionUtils() { LogUtils.d(TAG, "initPermissionUtils()"); mPermissionUtils = PermissionUtils.getInstance(); + LogUtils.d(TAG, "initPermissionUtils: 权限工具类已初始化"); } private void initGlobalHandler() { @@ -255,10 +268,10 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override public void handleMessage(Message msg) { if (sMainActivity == null || sMainActivity.isFinishing() || sMainActivity.isDestroyed()) { - LogUtils.w(TAG, "handleMessage: Activity已销毁,跳过消息 | what=" + msg.what); + LogUtils.w(TAG, String.format("handleMessage: Activity已销毁,跳过消息 | what=%d", msg.what)); return; } - LogUtils.d(TAG, "handleMessage() | what=" + msg.what); + LogUtils.d(TAG, String.format("handleMessage() | what=%d", msg.what)); switch (msg.what) { case MSG_RELOAD_APPCONFIG: sMainActivity.updateViewData(); @@ -266,12 +279,11 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV case MSG_CURRENTVALUEBATTERY: if (sMainActivity.mMainContentView != null) { sMainActivity.mMainContentView.updateCurrentBattery(msg.arg1); - LogUtils.d(TAG, "handleMessage: 更新当前电量 | value=" + msg.arg1); + LogUtils.d(TAG, String.format("handleMessage: 更新当前电量 | value=%d", msg.arg1)); } break; case MSG_LOAD_BACKGROUND: sMainActivity.reloadBackground(); - //sMainActivity.setMainLayoutBackgroundColor(); break; case MSG_UPDATE_SERVICE_SWITCH: sMainActivity.updateServiceSwitchUI(); @@ -279,6 +291,9 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV } } }; + LogUtils.d(TAG, "initGlobalHandler: 全局Handler已创建"); + } else { + LogUtils.d(TAG, "initGlobalHandler: 全局Handler已存在,无需重复创建"); } } @@ -286,6 +301,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV LogUtils.d(TAG, "initMainContentView()"); View rootView = findViewById(android.R.id.content); mMainContentView = new MainContentView(this, rootView, this); + LogUtils.d(TAG, "initMainContentView: 核心内容视图已初始化"); } private void initCriticalView() { @@ -295,8 +311,10 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV setSupportActionBar(mToolbar); if (mToolbar != null) { mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); + LogUtils.d(TAG, "initCriticalView: 工具栏已设置标题样式"); } mAdsViewStub = findViewById(R.id.stub_ads_banner); + LogUtils.d(TAG, "initCriticalView: 广告ViewStub已获取"); } private void initCoreUtilsAsync() { @@ -304,7 +322,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV new Thread(new Runnable() { @Override public void run() { - LogUtils.d(TAG, "initCoreUtilsAsync: 异步线程启动 | threadId=" + Thread.currentThread().getId()); + LogUtils.d(TAG, String.format("initCoreUtilsAsync: 异步线程启动 | threadId=%d", Thread.currentThread().getId())); mApplication = (App) getApplication(); mAppConfigUtils = AppConfigUtils.getInstance(getApplicationContext()); mBgSourceUtils = BackgroundSourceUtils.getInstance(getActivity()); @@ -314,17 +332,20 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV if (mServiceControlBean == null) { mServiceControlBean = new ControlCenterServiceBean(false); ControlCenterServiceBean.saveBean(getApplicationContext(), mServiceControlBean); + LogUtils.d(TAG, "initCoreUtilsAsync: 服务配置不存在,已创建默认配置"); } // 根据配置启停服务 final boolean isServiceEnable = mServiceControlBean.isEnableService(); final boolean isServiceAlive = ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName()); - LogUtils.d(TAG, "initCoreUtilsAsync: 服务配置状态 | isServiceEnable=" + isServiceEnable + " | isServiceAlive=" + isServiceAlive); + LogUtils.d(TAG, String.format("initCoreUtilsAsync: 服务配置状态 | isServiceEnable=%b | isServiceAlive=%b", + isServiceEnable, isServiceAlive)); if (isServiceEnable && !isServiceAlive) { runOnUiThread(new Runnable() { @Override public void run() { ControlCenterService.startControlCenterService(getApplicationContext()); + LogUtils.d(TAG, "initCoreUtilsAsync: 服务已启动"); } }); } else if (!isServiceEnable && isServiceAlive) { @@ -332,6 +353,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV @Override public void run() { ControlCenterService.stopControlCenterService(getApplicationContext()); + LogUtils.d(TAG, "initCoreUtilsAsync: 服务已停止"); } }); } @@ -353,6 +375,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV updateViewData(); sGlobalHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND); sGlobalHandler.sendEmptyMessage(MSG_UPDATE_SERVICE_SWITCH); + LogUtils.d(TAG, "initCoreUtilsAsync: UI更新消息已发送"); } }); } @@ -360,7 +383,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV } private void loadNonCriticalViewDelayed() { - LogUtils.d(TAG, "loadNonCriticalViewDelayed() | 延迟时长=" + DELAY_LOAD_NON_CRITICAL + "ms"); + LogUtils.d(TAG, String.format("loadNonCriticalViewDelayed() | 延迟时长=%dms", DELAY_LOAD_NON_CRITICAL)); new Handler().postDelayed(new Runnable() { @Override public void run() { @@ -383,6 +406,9 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV if (mADsBannerView == null) { View adsView = mAdsViewStub.inflate(); mADsBannerView = adsView.findViewById(R.id.adsbanner); + LogUtils.d(TAG, "loadAdsView: 广告视图已加载"); + } else { + LogUtils.d(TAG, "loadAdsView: 广告视图已存在,无需重复加载"); } } @@ -393,6 +419,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV return; } mMainContentView.updateViewData(mFrameDrawable); + LogUtils.d(TAG, "updateViewData: 视图数据已更新"); } private void reloadBackground() { @@ -403,25 +430,15 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV } BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean(); if (currentBgBean != null) { + //ToastUtils.show("currentBgBean"); mMainContentView.backgroundView.loadByBackgroundBean(currentBgBean, true); + LogUtils.d(TAG, "reloadBackground: 已加载自定义背景"); } else { mMainContentView.backgroundView.setBackgroundResource(R.drawable.default_background); + LogUtils.d(TAG, "reloadBackground: 已加载默认背景"); } } -// private void setMainLayoutBackgroundColor() { -// LogUtils.d(TAG, "setMainLayoutBackgroundColor()"); -// if (isFinishing() || isDestroyed() || mMainContentView == null || mBgSourceUtils == null) { -// LogUtils.e(TAG, "setMainLayoutBackgroundColor: 上下文无效,设置失败"); -// return; -// } -// BackgroundBean currentBgBean = mBgSourceUtils.getCurrentBackgroundBean(); -// if (currentBgBean != null) { -// mMainContentView.mainLayout.setBackgroundColor(currentBgBean.getPixelColor()); -// LogUtils.d(TAG, "setMainLayoutBackgroundColor: 主布局背景色设置完成 | color=" + currentBgBean.getPixelColor2()); -// } -// } - private void updateServiceSwitchUI() { LogUtils.d(TAG, "updateServiceSwitchUI()"); if (mMainContentView == null || mServiceControlBean == null) { @@ -432,25 +449,29 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV mMainContentView.setServiceSwitchEnabled(false); mMainContentView.setServiceSwitchChecked(configEnabled); mMainContentView.setServiceSwitchEnabled(true); + LogUtils.d(TAG, String.format("updateServiceSwitchUI: 服务开关已更新 | 状态=%b", configEnabled)); } // ======================== 服务与线程管理方法 ======================== private void toggleServiceEnableState(boolean isEnable) { - LogUtils.d(TAG, "toggleServiceEnableState() | 目标状态=" + isEnable); + LogUtils.d(TAG, String.format("toggleServiceEnableState() | 目标状态=%b", isEnable)); if (mServiceControlBean == null) { LogUtils.e(TAG, "toggleServiceEnableState: 服务配置为空,切换失败"); return; } mServiceControlBean.setIsEnableService(isEnable); ControlCenterServiceBean.saveBean(getApplicationContext(), mServiceControlBean); + LogUtils.d(TAG, "toggleServiceEnableState: 服务配置已保存"); // UI开关联动服务启停 if (isEnable) { if (!ServiceUtils.isServiceAlive(getApplicationContext(), ControlCenterService.class.getName())) { ControlCenterService.startControlCenterService(getApplicationContext()); + LogUtils.d(TAG, "toggleServiceEnableState: 服务已启动"); } } else { ControlCenterService.stopControlCenterService(getApplicationContext()); + LogUtils.d(TAG, "toggleServiceEnableState: 服务已停止"); } sGlobalHandler.sendEmptyMessage(MSG_UPDATE_SERVICE_SWITCH); @@ -463,6 +484,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV APPInfo appInfo = genDefaultAppInfo(); aboutIntent.putExtra(AboutActivity.EXTRA_APPINFO, appInfo); WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), aboutIntent, AboutActivity.class); + LogUtils.d(TAG, "startAboutActivity: 关于页面已启动"); } // ======================== 消息发送方法 ======================== @@ -470,23 +492,26 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV LogUtils.d(TAG, "notifyServiceAppConfigChange()"); ControlCenterService.sendAppConfigStatusUpdateMessage(this); reloadAppConfig(); + LogUtils.d(TAG, "notifyServiceAppConfigChange: 服务配置已通知更新"); } public static void reloadAppConfig() { LogUtils.d(TAG, "reloadAppConfig()"); if (sGlobalHandler != null) { sGlobalHandler.sendEmptyMessage(MSG_RELOAD_APPCONFIG); + LogUtils.d(TAG, "reloadAppConfig: 配置重载消息已发送"); } else { LogUtils.w(TAG, "reloadAppConfig: 全局Handler为空,消息发送失败"); } } public static void sendCurrentBatteryValueMessage(int value) { - LogUtils.d(TAG, "sendCurrentBatteryValueMessage() | 电量=" + value); + LogUtils.d(TAG, String.format("sendCurrentBatteryValueMessage() | 电量=%d", value)); if (sGlobalHandler != null) { Message msg = sGlobalHandler.obtainMessage(MSG_CURRENTVALUEBATTERY); msg.arg1 = value; sGlobalHandler.sendMessage(msg); + LogUtils.d(TAG, "sendCurrentBatteryValueMessage: 电量消息已发送"); } else { LogUtils.w(TAG, "sendCurrentBatteryValueMessage: 全局Handler为空,消息发送失败"); } @@ -507,37 +532,38 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV appInfo.setAppHomePage("https://www.winboll.cc/apks/index.php?project=PowerBell"); appInfo.setAppAPKName("PowerBell"); appInfo.setAppAPKFolderName("PowerBell"); + LogUtils.d(TAG, "genDefaultAppInfo: 应用信息已生成"); return appInfo; } // ======================== MainContentView 事件回调 ======================== @Override public void onChargeReminderSwitchChanged(boolean isChecked) { - LogUtils.d(TAG, "onChargeReminderSwitchChanged() | isChecked=" + isChecked); + LogUtils.d(TAG, String.format("onChargeReminderSwitchChanged() | isChecked=%b", isChecked)); notifyServiceAppConfigChange(); } @Override public void onUsageReminderSwitchChanged(boolean isChecked) { - LogUtils.d(TAG, "onUsageReminderSwitchChanged() | isChecked=" + isChecked); + LogUtils.d(TAG, String.format("onUsageReminderSwitchChanged() | isChecked=%b", isChecked)); notifyServiceAppConfigChange(); } @Override public void onServiceSwitchChanged(boolean isChecked) { - LogUtils.d(TAG, "onServiceSwitchChanged() | isChecked=" + isChecked); + LogUtils.d(TAG, String.format("onServiceSwitchChanged() | isChecked=%b", isChecked)); toggleServiceEnableState(isChecked); } @Override public void onChargeReminderProgressChanged(int progress) { - LogUtils.d(TAG, "onChargeReminderProgressChanged() | progress=" + progress); + LogUtils.d(TAG, String.format("onChargeReminderProgressChanged() | progress=%d", progress)); notifyServiceAppConfigChange(); } @Override public void onUsageReminderProgressChanged(int progress) { - LogUtils.d(TAG, "onUsageReminderProgressChanged() | progress=" + progress); + LogUtils.d(TAG, String.format("onUsageReminderProgressChanged() | progress=%d", progress)); notifyServiceAppConfigChange(); } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java index c2b69a5..0102a5f 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java @@ -29,6 +29,7 @@ import cc.winboll.studio.powerbell.dialogs.BackgroundPicturePreviewDialog; import cc.winboll.studio.powerbell.dialogs.ColorPaletteDialog; import cc.winboll.studio.powerbell.dialogs.NetworkBackgroundDialog; import cc.winboll.studio.powerbell.models.BackgroundBean; +import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; import cc.winboll.studio.powerbell.utils.BitmapCacheUtils; import cc.winboll.studio.powerbell.utils.FileUtils; @@ -38,6 +39,11 @@ import cc.winboll.studio.powerbell.utils.UriUtils; import cc.winboll.studio.powerbell.views.BackgroundView; import java.io.File; +/** + * 背景设置页面(支持图片选择、拍照、裁剪、像素拾取、调色板等功能) + * 核心:基于强制缓存策略,支持预览与设置提交分离,保留操作状态 + * @Author 豆包&ZhanGSKen + */ public class BackgroundSettingsActivity extends WinBoLLActivity { // ====================== 常量定义(按功能分类置顶)====================== @@ -79,7 +85,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - LogUtils.d(TAG, "【生命周期】onCreate 开始初始化"); + LogUtils.d(TAG, "生命周期 onCreate 开始初始化"); setContentView(R.layout.activity_background_settings); // 初始化核心组件 @@ -87,44 +93,44 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { // 初始化界面与事件 initToolbar(); initClickListeners(); - LogUtils.d(TAG, "【初始化】界面与事件绑定完成"); + LogUtils.d(TAG, "初始化 界面与事件绑定完成"); // 处理分享意图或初始化预览 handleIntentOrPreview(); // 初始化预览环境并刷新 initPreviewEnvironment(); - LogUtils.d(TAG, "【生命周期】onCreate 初始化完成"); + LogUtils.d(TAG, "生命周期 onCreate 初始化完成"); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - LogUtils.d(TAG, "【生命周期】onPostCreate 执行双重刷新预览"); + LogUtils.d(TAG, "生命周期 onPostCreate 执行双重刷新预览"); doubleRefreshPreview(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - LogUtils.d(TAG, "【回调触发】requestCode:" + requestCode + ",resultCode:" + resultCode); + LogUtils.d(TAG, String.format("回调触发 requestCode=%d,resultCode=%d", requestCode, resultCode)); try { if (resultCode != RESULT_OK) { - LogUtils.d(TAG, "【回调处理】结果非RESULT_OK,执行取消逻辑"); + LogUtils.d(TAG, "回调处理 结果非RESULT_OK,执行取消逻辑"); handleOperationCancelOrFail(); return; } handleActivityResult(requestCode, data); } catch (Exception e) { - LogUtils.e(TAG, "【回调异常】requestCode:" + requestCode + ",异常信息:" + e.getMessage()); + LogUtils.e(TAG, String.format("回调异常 requestCode=%d,异常信息=%s", requestCode, e.getMessage())); ToastUtils.show("操作失败"); } } @Override public void finish() { - LogUtils.d(TAG, "【生命周期】finish 触发,isCommitSettings:" + isCommitSettings + ",isPreviewBackgroundChanged:" + isPreviewBackgroundChanged); + LogUtils.d(TAG, String.format("生命周期 finish 触发,isCommitSettings=%b,isPreviewBackgroundChanged=%b", isCommitSettings, isPreviewBackgroundChanged)); if (isCommitSettings) { super.finish(); } else { @@ -136,7 +142,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - LogUtils.d(TAG, "【权限回调】requestCode:" + requestCode + ",权限数量:" + permissions.length); + LogUtils.d(TAG, String.format("权限回调 requestCode=%d,权限数量=%d", requestCode, permissions.length)); if (requestCode == REQUEST_CAMERA_PERMISSION) { handleCameraPermissionResult(grantResults); } @@ -146,7 +152,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private void initToolbar() { mToolbar = findViewById(R.id.toolbar); if (mToolbar == null) { - LogUtils.e(TAG, "【初始化异常】Toolbar未找到"); + LogUtils.e(TAG, "初始化异常 Toolbar未找到"); return; } setSupportActionBar(mToolbar); @@ -156,15 +162,15 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【导航栏】点击返回按钮"); + LogUtils.d(TAG, "导航栏 点击返回按钮"); finish(); } }); - LogUtils.d(TAG, "【界面初始化】Toolbar 配置完成"); + LogUtils.d(TAG, "界面初始化 Toolbar 配置完成"); } private void initClickListeners() { - LogUtils.d(TAG, "【界面初始化】开始绑定按钮点击事件"); + LogUtils.d(TAG, "界面初始化 开始绑定按钮点击事件"); // 绑定所有按钮点击事件 bindClickListener(R.id.activitybackgroundsettingsAButton1, onOriginNullClickListener); bindClickListener(R.id.activitybackgroundsettingsAButton2, onReceivedPictureClickListener); @@ -176,7 +182,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { bindClickListener(R.id.activitybackgroundsettingsAButton8, onPixelPickerClickListener); bindClickListener(R.id.activitybackgroundsettingsAButton9, onColorPaletteClickListener); bindClickListener(R.id.activitybackgroundsettingsAButton10, onCleanPixelClickListener); - LogUtils.d(TAG, "【界面初始化】按钮点击事件绑定完成"); + LogUtils.d(TAG, "界面初始化 按钮点击事件绑定完成"); } // 通用按钮绑定工具方法 @@ -185,7 +191,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { if (view != null) { view.setOnClickListener(listener); } else { - LogUtils.e(TAG, "【绑定异常】未找到视图:" + resId); + LogUtils.e(TAG, String.format("绑定异常 未找到视图:%d", resId)); } } @@ -193,10 +199,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onOriginNullClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】取消背景图片"); + LogUtils.d(TAG, "按钮点击 取消背景图片"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【操作异常】预览Bean为空"); + LogUtils.e(TAG, "操作异常 预览Bean为空"); return; } previewBean.setIsUseBackgroundFile(false); @@ -209,15 +215,15 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onSelectPictureClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】选择图片"); + LogUtils.d(TAG, "按钮点击 选择图片"); launchImageSelector(); } }; - private View.OnClickListener onNetworkBackgroundDialog = new View.OnClickListener() { + private View.OnClickListener onNetworkBackgroundDialog = new View.OnClickListener() { @Override public void onClick(View v) { - NetworkBackgroundDialog networkBackgroundDialog = new NetworkBackgroundDialog(BackgroundSettingsActivity.this, new NetworkBackgroundDialog.OnDialogClickListener(){ + NetworkBackgroundDialog networkBackgroundDialog = new NetworkBackgroundDialog(BackgroundSettingsActivity.this, new NetworkBackgroundDialog.OnDialogClickListener() { @Override public void onConfirm(String szConfirmFilePath) { // 拷贝文件到预览数据并启动裁剪 @@ -230,14 +236,14 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { public void onCancel() { } }); - networkBackgroundDialog.show(); + networkBackgroundDialog.show(); } }; private View.OnClickListener onCropPictureClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】固定比例裁剪"); + LogUtils.d(TAG, "按钮点击 固定比例裁剪"); startImageCrop(false); } }; @@ -245,7 +251,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onCropFreePictureClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】自由裁剪"); + LogUtils.d(TAG, "按钮点击 自由裁剪"); startImageCrop(true); } }; @@ -253,11 +259,11 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onTakePhotoClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】拍照"); + LogUtils.d(TAG, "按钮点击 拍照"); // 动态申请相机权限 if (ContextCompat.checkSelfPermission(BackgroundSettingsActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - LogUtils.d(TAG, "【拍照准备】相机权限未授予,发起申请"); + LogUtils.d(TAG, "拍照准备 相机权限未授予,发起申请"); ActivityCompat.requestPermissions( BackgroundSettingsActivity.this, new String[]{Manifest.permission.CAMERA}, @@ -271,10 +277,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onReceivedPictureClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】恢复收到的图片"); + LogUtils.d(TAG, "按钮点击 恢复收到的图片"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【操作异常】预览Bean为空"); + LogUtils.e(TAG, "操作异常 预览Bean为空"); return; } previewBean.setIsUseBackgroundFile(true); @@ -287,10 +293,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private View.OnClickListener onPixelPickerClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】像素拾取"); + LogUtils.d(TAG, "按钮点击 像素拾取"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【操作异常】预览Bean为空"); + LogUtils.e(TAG, "操作异常 预览Bean为空"); ToastUtils.show("无有效图片可拾取像素"); return; } @@ -298,23 +304,23 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { File targetFile = new File(targetImagePath); if (targetFile == null || !targetFile.exists() || targetFile.length() <= 0) { ToastUtils.show("无有效图片可拾取像素"); - LogUtils.e(TAG, "【像素拾取失败】文件无效:" + targetImagePath); + LogUtils.e(TAG, String.format("像素拾取失败 文件无效:%s", targetImagePath)); return; } Intent intent = new Intent(getApplicationContext(), PixelPickerActivity.class); intent.putExtra("imagePath", targetImagePath); startActivityForResult(intent, REQUEST_PIXELPICKER); - LogUtils.d(TAG, "【像素拾取启动】路径:" + targetImagePath); + LogUtils.d(TAG, String.format("像素拾取启动 路径:%s", targetImagePath)); } }; private View.OnClickListener onCleanPixelClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】清空像素颜色"); + LogUtils.d(TAG, "按钮点击 清空像素颜色"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【操作异常】预览Bean为空"); + LogUtils.e(TAG, "操作异常 预览Bean为空"); return; } int oldColor = previewBean.getPixelColor(); @@ -323,21 +329,21 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { doubleRefreshPreview(); isPreviewBackgroundChanged = true; ToastUtils.show("像素颜色已清空"); - LogUtils.d(TAG, "【像素清空】旧颜色:" + String.format("#%08X", oldColor)); + LogUtils.d(TAG, String.format("像素清空 旧颜色:#%08X", oldColor)); } }; private View.OnClickListener onColorPaletteClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - LogUtils.d(TAG, "【按钮点击】调色板按钮"); + LogUtils.d(TAG, "按钮点击 调色板按钮"); final BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【操作异常】预览Bean为空"); + LogUtils.e(TAG, "操作异常 预览Bean为空"); return; } int initialColor = previewBean.getPixelColor(); - LogUtils.d(TAG, "【调色板】初始颜色:" + String.format("#%08X", initialColor)); + LogUtils.d(TAG, String.format("调色板 初始颜色:#%08X", initialColor)); ColorPaletteDialog dialog = new ColorPaletteDialog(BackgroundSettingsActivity.this, initialColor, new ColorPaletteDialog.OnColorSelectedListener() { @Override public void onColorSelected(int color) { @@ -345,11 +351,11 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { mBgSourceUtils.saveSettings(); doubleRefreshPreview(); isPreviewBackgroundChanged = true; - LogUtils.d(TAG, "【颜色选择】选中颜色:" + String.format("#%08X", color)); + LogUtils.d(TAG, String.format("颜色选择 选中颜色:#%08X", color)); } }); dialog.show(); - LogUtils.d(TAG, "【调色板】对话框已显示"); + LogUtils.d(TAG, "调色板 对话框已显示"); } }; @@ -360,9 +366,9 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @return 适配后的Uri,失败返回null */ public Uri getFileProviderUri(File file) { - LogUtils.d(TAG, "【工具方法】生成FileProvider Uri,文件路径:" + (file != null ? file.getAbsolutePath() : "null")); + LogUtils.d(TAG, String.format("工具方法 生成FileProvider Uri,文件路径:%s", (file != null ? file.getAbsolutePath() : "null"))); if (file == null) { - LogUtils.e(TAG, "【工具异常】文件为空"); + LogUtils.e(TAG, "工具异常 文件为空"); return null; } try { @@ -373,7 +379,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { return Uri.fromFile(file); } } catch (Exception e) { - LogUtils.e(TAG, "【工具异常】生成Uri失败:" + e.getMessage()); + LogUtils.e(TAG, String.format("工具异常 生成Uri失败:%s", e.getMessage())); return null; } } @@ -385,7 +391,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { */ private boolean isBitmapValid(Bitmap bitmap) { boolean isValid = bitmap != null && !bitmap.isRecycled(); - LogUtils.d(TAG, "【工具方法】Bitmap有效性校验:" + isValid); + LogUtils.d(TAG, String.format("工具方法 Bitmap有效性校验:%b", isValid)); return isValid; } @@ -393,9 +399,9 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * 双重刷新预览,确保背景加载最新数据 */ private void doubleRefreshPreview() { - LogUtils.d(TAG, "【工具方法】开始双重刷新预览"); + LogUtils.d(TAG, "工具方法 开始双重刷新预览"); if (mBgSourceUtils == null || mBackgroundView == null || isFinishing()) { - LogUtils.w(TAG, "【双重刷新】跳过:对象为空或Activity已结束"); + LogUtils.w(TAG, "双重刷新 跳过:对象为空或Activity已结束"); return; } @@ -404,10 +410,9 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { mBgSourceUtils.loadSettings(); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); mBackgroundView.loadByBackgroundBean(previewBean, true); - //mBackgroundView.setBackgroundColor(previewBean.getPixelColor()); - LogUtils.d(TAG, "【双重刷新】第一重完成"); + LogUtils.d(TAG, "双重刷新 第一重完成"); } catch (Exception e) { - LogUtils.e(TAG, "【双重刷新】第一重异常:" + e.getMessage()); + LogUtils.e(TAG, String.format("双重刷新 第一重异常:%s", e.getMessage())); return; } @@ -420,10 +425,9 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { mBgSourceUtils.loadSettings(); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); mBackgroundView.loadByBackgroundBean(previewBean, true); - //mBackgroundView.setBackgroundColor(previewBean.getPixelColor()); - LogUtils.d(TAG, "【双重刷新】第二重完成"); + LogUtils.d(TAG, "双重刷新 第二重完成"); } catch (Exception e) { - LogUtils.e(TAG, "【双重刷新】第二重异常:" + e.getMessage()); + LogUtils.e(TAG, String.format("双重刷新 第二重异常:%s", e.getMessage())); } } } @@ -438,13 +442,13 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { // 初始化视图 mBackgroundView = findViewById(R.id.background_view); if (mBackgroundView == null) { - LogUtils.e(TAG, "【初始化异常】BackgroundView未找到"); + LogUtils.e(TAG, "初始化异常 BackgroundView未找到"); } // 初始化工具类 mBgSourceUtils = BackgroundSourceUtils.getInstance(this); mBgSourceUtils.loadSettings(); mBitmapCache = BitmapCacheUtils.getInstance(); - LogUtils.d(TAG, "【初始化】视图与工具类加载完成"); + LogUtils.d(TAG, "初始化 视图与工具类加载完成"); } /** @@ -455,7 +459,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { ToastUtils.show("已接收分享图片"); } else { mBgSourceUtils.setCurrentSourceToPreview(); - LogUtils.d(TAG, "【预览初始化】加载当前背景配置"); + LogUtils.d(TAG, "预览初始化 加载当前背景配置"); } } @@ -477,7 +481,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { if (intent != null) { String action = intent.getAction(); String type = intent.getType(); - LogUtils.d(TAG, "【分享处理】action:" + action + ",type:" + type); + LogUtils.d(TAG, String.format("分享处理 action:%s,type:%s", action, type)); if (Intent.ACTION_SEND.equals(action) && type != null && isImageType(type)) { showSharePreviewDialog(); return true; @@ -490,7 +494,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * 显示分享图片预览对话框 */ private void showSharePreviewDialog() { - LogUtils.d(TAG, "showSharePreviewDialog()"); + LogUtils.d(TAG, "showSharePreviewDialog()"); BackgroundPicturePreviewDialog dlg = new BackgroundPicturePreviewDialog(this, new BackgroundPicturePreviewDialog.IOnRecivedPictureListener() { @Override public void onAcceptRecivedPicture(Uri uriRecivedPicture) { @@ -500,7 +504,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { } }); dlg.show(); - LogUtils.d(TAG, "【分享处理】显示图片预览对话框"); + LogUtils.d(TAG, "分享处理 显示图片预览对话框"); } /** @@ -509,19 +513,19 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @return 是图片返回true,否则false */ private boolean isImageType(String mimeType) { - if (mimeType == null) { - return false; - } - String lowerMimeType = mimeType.toLowerCase(); - LogUtils.d("isImageType", "mimeType: " + mimeType + ", lowerMimeType: " + lowerMimeType); - return lowerMimeType.startsWith("image/"); - } - + if (mimeType == null) { + return false; + } + String lowerMimeType = mimeType.toLowerCase(); + LogUtils.d("isImageType", String.format("mimeType: %s, lowerMimeType: %s", mimeType, lowerMimeType)); + return lowerMimeType.startsWith("image/"); + } + /** * 启动图片选择器 */ private void launchImageSelector() { - LogUtils.d(TAG, "【业务逻辑】启动图片选择器"); + LogUtils.d(TAG, "业务逻辑 启动图片选择器"); Intent[] intents = createImageSelectorIntents(); Intent validIntent = findValidIntent(intents); @@ -584,14 +588,14 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { Intent chooser = Intent.createChooser(validIntent, "选择图片"); chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); startActivityForResult(chooser, REQUEST_SELECT_PICTURE); - LogUtils.d(TAG, "【选图意图】启动图片选择"); + LogUtils.d(TAG, "选图意图 启动图片选择"); } /** * 显示无相册应用提示对话框 */ private void showNoGalleryDialog() { - LogUtils.d(TAG, "【选图意图】无相册应用"); + LogUtils.d(TAG, "选图意图 无相册应用"); runOnUiThread(new Runnable() { @Override public void run() { @@ -629,7 +633,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { */ private void handleOperationCancelOrFail() { mBgSourceUtils.setCurrentSourceToPreview(); - LogUtils.d(TAG, "【业务逻辑】操作取消或失败,恢复预览"); + LogUtils.d(TAG, "业务逻辑 操作取消或失败,恢复预览"); ToastUtils.show("操作取消或失败"); doubleRefreshPreview(); } @@ -638,10 +642,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * 处理拍照逻辑(权限通过后执行) */ void handleTakePhoto() { - LogUtils.d(TAG, "【业务逻辑】开始处理拍照"); + LogUtils.d(TAG, "业务逻辑 开始处理拍照"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【拍照失败】预览Bean为空"); + LogUtils.e(TAG, "拍照失败 预览Bean为空"); ToastUtils.show("拍照文件创建失败"); return; } @@ -649,7 +653,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { File takePhotoFile = new File(previewBean.getBackgroundFilePath()); if (!takePhotoFile.exists()) { ToastUtils.show("拍照文件创建失败"); - LogUtils.e(TAG, "【拍照失败】文件不存在:" + takePhotoFile.getAbsolutePath()); + LogUtils.e(TAG, String.format("拍照失败 文件不存在:%s", takePhotoFile.getAbsolutePath())); return; } @@ -661,11 +665,11 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { } takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); - LogUtils.d(TAG, "【拍照启动】Uri:" + photoUri.toString()); + LogUtils.d(TAG, String.format("拍照启动 Uri:%s", photoUri.toString())); } catch (Exception e) { String errMsg = "拍照启动异常:" + e.getMessage(); ToastUtils.show(errMsg.substring(0, 20)); - LogUtils.e(TAG, "【拍照失败】" + e.getMessage()); + LogUtils.e(TAG, String.format("拍照失败 %s", e.getMessage())); } } @@ -689,7 +693,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { handlePixelPickerResult(); break; default: - LogUtils.d(TAG, "【回调忽略】未知requestCode:" + requestCode); + LogUtils.d(TAG, String.format("回调忽略 未知requestCode:%d", requestCode)); break; } } @@ -699,10 +703,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @param data 回调数据 */ private void handleTakePhotoResult(Intent data) { - LogUtils.d(TAG, "【业务逻辑】处理拍照结果"); + LogUtils.d(TAG, "业务逻辑 处理拍照结果"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【拍照结果处理】预览Bean为空"); + LogUtils.e(TAG, "拍照结果处理 预览Bean为空"); return; } @@ -712,7 +716,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { doubleRefreshPreview(); startImageCrop(false); - LogUtils.d(TAG, "【拍照完成】已启动裁剪"); + LogUtils.d(TAG, "拍照完成 已启动裁剪"); } /** @@ -720,30 +724,30 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @param data 回调数据 */ private void handleSelectPictureResult(Intent data) { - LogUtils.d(TAG, "【业务逻辑】处理选图结果"); + LogUtils.d(TAG, "业务逻辑 处理选图结果"); Uri selectedImage = data.getData(); if (selectedImage == null) { ToastUtils.show("图片Uri为空"); - LogUtils.e(TAG, "【选图结果】Uri为空"); + LogUtils.e(TAG, "选图结果 Uri为空"); return; } - LogUtils.d(TAG, "【选图回调】系统返回Uri : " + selectedImage.toString()); + LogUtils.d(TAG, String.format("选图回调 系统返回Uri : %s", selectedImage.toString())); // 申请持久化权限(API33+) if (Build.VERSION.SDK_INT >= SDK_VERSION_TIRAMISU) { getContentResolver().takePersistableUriPermission( selectedImage, Intent.FLAG_GRANT_READ_URI_PERMISSION); - LogUtils.d(TAG, "【选图权限】已添加持久化权限"); + LogUtils.d(TAG, "选图权限 已添加持久化权限"); } // 同步文件并启动裁剪 if (putUriFileToPreviewSource(selectedImage)) { - LogUtils.d(TAG, "【选图同步】路径绑定完成"); + LogUtils.d(TAG, "选图同步 路径绑定完成"); startImageCrop(false); } else { ToastUtils.show("图片同步失败"); - LogUtils.e(TAG, "【选图同步】文件复制失败"); + LogUtils.e(TAG, "选图同步 文件复制失败"); } } @@ -755,7 +759,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private boolean putUriFileToPreviewSource(Uri srcUriFile) { String filePath = UriUtils.getFilePathFromUri(this, srcUriFile); if (TextUtils.isEmpty(filePath)) { - LogUtils.e(TAG, "【选图同步】Uri解析路径为空"); + LogUtils.e(TAG, "选图同步 Uri解析路径为空"); return false; } File srcFile = new File(filePath); @@ -768,16 +772,16 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @return 同步成功返回true,否则false */ private boolean putUriFileToPreviewSource(File srcFile) { - LogUtils.d(TAG, "【选图同步】源文件:" + srcFile.getAbsolutePath()); + LogUtils.d(TAG, String.format("选图同步 源文件:%s", srcFile.getAbsolutePath())); mBgSourceUtils.loadSettings(); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); File dstFile = new File(previewBean.getBackgroundFilePath()); - LogUtils.d(TAG, "【选图同步】目标文件:" + dstFile.getAbsolutePath()); + LogUtils.d(TAG, String.format("选图同步 目标文件:%s", dstFile.getAbsolutePath())); if (FileUtils.copyFile(srcFile, dstFile)) { - LogUtils.d(TAG, "【选图同步】文件拷贝成功"); + LogUtils.d(TAG, "选图同步 文件拷贝成功"); return true; } - LogUtils.d(TAG, "【选图同步】文件无法拷贝"); + LogUtils.d(TAG, "选图同步 文件无法拷贝"); return false; } @@ -786,10 +790,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { * @param data 回调数据 */ private void handleCropImageResult(Intent data) { - LogUtils.d(TAG, "【业务逻辑】处理裁剪结果"); + LogUtils.d(TAG, "业务逻辑 处理裁剪结果"); BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【裁剪结果处理】预览Bean为空"); + LogUtils.e(TAG, "裁剪结果处理 预览Bean为空"); handleOperationCancelOrFail(); return; } @@ -814,11 +818,11 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { */ private void handleCropSuccess(BackgroundBean previewBean, long fileSize) { isPreviewBackgroundChanged = true; - LogUtils.d(TAG, "【裁剪结果】裁剪成功,文件大小:" + fileSize); + LogUtils.d(TAG, String.format("裁剪结果 裁剪成功,文件大小:%d", fileSize)); previewBean.setIsUseBackgroundFile(true); previewBean.setIsUseBackgroundScaledCompressFile(true); mBgSourceUtils.saveSettings(); - doubleRefreshPreview(); + doubleRefreshPreview(); } /** @@ -829,14 +833,14 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { */ private void handleCropFailure(boolean isFileExist, boolean isFileReadable, long fileSize) { handleOperationCancelOrFail(); - LogUtils.e(TAG, "【裁剪结果】裁剪失败,文件状态:存在=" + isFileExist + ",可读=" + isFileReadable + ",大小=" + fileSize); + LogUtils.e(TAG, String.format("裁剪结果 裁剪失败,文件状态:存在=%b,可读=%b,大小=%d", isFileExist, isFileReadable, fileSize)); } /** * 处理像素拾取结果 */ private void handlePixelPickerResult() { - LogUtils.d(TAG, "【业务逻辑】处理像素拾取结果"); + LogUtils.d(TAG, "业务逻辑 处理像素拾取结果"); doubleRefreshPreview(); isPreviewBackgroundChanged = true; } @@ -847,10 +851,10 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { */ private void handleCameraPermissionResult(int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - LogUtils.d(TAG, "【权限申请】相机权限授予成功"); + LogUtils.d(TAG, "权限申请 相机权限授予成功"); handleTakePhoto(); } else { - LogUtils.d(TAG, "【权限申请】相机权限授予失败"); + LogUtils.d(TAG, "权限申请 相机权限授予失败"); ToastUtils.show("相机权限被拒绝,无法拍照"); // 引导用户到设置页面开启权限(用户选择不再询问时) if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { @@ -868,7 +872,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { intent.setData(uri); startActivity(intent); ToastUtils.show("请在设置中开启相机权限"); - LogUtils.d(TAG, "【权限引导】启动应用设置页面"); + LogUtils.d(TAG, "权限引导 启动应用设置页面"); } /** @@ -903,7 +907,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { private void startImageCrop(boolean isFreeCrop) { BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean(); if (previewBean == null) { - LogUtils.e(TAG, "【裁剪启动】预览Bean为空"); + LogUtils.e(TAG, "裁剪启动 预览Bean为空"); ToastUtils.show("裁剪失败:无有效图片"); return; } @@ -915,7 +919,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { height, isFreeCrop, REQUEST_CROP_IMAGE); - LogUtils.d(TAG, "【裁剪启动】是否自由裁剪:" + isFreeCrop + ",目标尺寸:" + width + "x" + height); + LogUtils.d(TAG, String.format("裁剪启动 是否自由裁剪:%b,目标尺寸:%dx%d", isFreeCrop, width, height)); } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/models/AppConfigBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/models/AppConfigBean.java index 6cf1c0c..0d3409c 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/models/AppConfigBean.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/models/AppConfigBean.java @@ -14,7 +14,7 @@ import java.io.Serializable; * @Date 2024/04/29 17:24:53 * @Describe 应用运行参数类 * 适配 API30,支持 Serializable 持久化、Parcelable Intent 传递、JSON 序列化/反序列化 - * 包含耗电提醒、充电提醒、电量检测、铃声提醒等核心配置 + * 包含耗电提醒、充电提醒、电量检测、铃声提醒、相框尺寸等核心配置 */ public class AppConfigBean extends BaseBean implements Serializable, Parcelable { // ====================== 静态常量(首屏可见,统一管理) ====================== @@ -28,8 +28,12 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable private static final int BATTERY_MIN = 0; // 电量最小值 private static final int BATTERY_MAX = 100; // 电量最大值 private static final int INVALID_BATTERY = -1; // 无效电量标识 + private static final int MIN_FRAME_SIZE = 100; // 最小相框尺寸(px) + private static final int MAX_FRAME_SIZE = 2000; // 最大相框尺寸(px) + private static final int DEFAULT_FRAME_WIDTH = 500; // 默认相框宽度(px) + private static final int DEFAULT_FRAME_HEIGHT = 500; // 默认相框高度(px) - // ====================== 成员变量(按功能分类:提醒配置→电量状态→检测配置) ====================== + // ====================== 成员变量(按功能分类:提醒配置→电量状态→检测配置→相框配置) ====================== // 耗电提醒配置 boolean isEnableUsageReminder = false; // 耗电提醒开关 int usageReminderValue = 45; // 耗电提醒阈值(0-100) @@ -43,6 +47,9 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable int currentBatteryValue = INVALID_BATTERY; // 当前电池电量(统一命名,替代原 currentValue) // 电量检测配置 int batteryDetectInterval = 2000; // 电量检测间隔(ms,适配 RemindThread) + // 相框配置 + int defaultFrameWidth = DEFAULT_FRAME_WIDTH; // 默认相框宽度(px) + int defaultFrameHeight = DEFAULT_FRAME_HEIGHT; // 默认相框高度(px) // ====================== 构造方法(初始化默认配置,强化默认值校验) ====================== public AppConfigBean() { @@ -53,6 +60,8 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable setReminderIntervalTime(5000); setBatteryDetectInterval(1000); // 默认检测间隔1秒 setCurrentBatteryValue(INVALID_BATTERY); // 初始化无效电量标识 + setDefaultFrameWidth(DEFAULT_FRAME_WIDTH); // 初始化默认相框宽度 + setDefaultFrameHeight(DEFAULT_FRAME_HEIGHT); // 初始化默认相框高度 LogUtils.d(TAG, "AppConfigBean: 初始化默认配置完成"); } @@ -169,6 +178,35 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable return batteryDetectInterval; } + // --------------- 相框配置相关 --------------- + /** + * 设置默认相框宽度 + * @param defaultFrameWidth 相框宽度(px,范围 MIN_FRAME_SIZE - MAX_FRAME_SIZE) + */ + public void setDefaultFrameWidth(int defaultFrameWidth) { + this.defaultFrameWidth = Math.min(Math.max(defaultFrameWidth, MIN_FRAME_SIZE), MAX_FRAME_SIZE); + LogUtils.d(TAG, String.format("setDefaultFrameWidth: 默认相框宽度设置为 %dpx(输入值:%d)", + this.defaultFrameWidth, defaultFrameWidth)); + } + + public int getDefaultFrameWidth() { + return defaultFrameWidth; + } + + /** + * 设置默认相框高度 + * @param defaultFrameHeight 相框高度(px,范围 MIN_FRAME_SIZE - MAX_FRAME_SIZE) + */ + public void setDefaultFrameHeight(int defaultFrameHeight) { + this.defaultFrameHeight = Math.min(Math.max(defaultFrameHeight, MIN_FRAME_SIZE), MAX_FRAME_SIZE); + LogUtils.d(TAG, String.format("setDefaultFrameHeight: 默认相框高度设置为 %dpx(输入值:%d)", + this.defaultFrameHeight, defaultFrameHeight)); + } + + public int getDefaultFrameHeight() { + return defaultFrameHeight; + } + // ====================== JSON 序列化/反序列化(兼容旧配置,补充调试日志) ====================== @Override public String getName() { @@ -189,8 +227,11 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable // 兼容旧字段 currentValue,同步新字段 currentBatteryValue jsonWriter.name("currentBatteryValue").value(bean.getCurrentBatteryValue()); jsonWriter.name("currentValue").value(bean.getCurrentBatteryValue()); - // 新增字段序列化 + // 新增字段序列化(检测配置) jsonWriter.name("batteryDetectInterval").value(bean.getBatteryDetectInterval()); + // 新增字段序列化(相框配置) + jsonWriter.name("defaultFrameWidth").value(bean.getDefaultFrameWidth()); + jsonWriter.name("defaultFrameHeight").value(bean.getDefaultFrameHeight()); LogUtils.d(TAG, "writeThisToJsonWriter: JSON 序列化完成"); } @@ -223,6 +264,12 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable LogUtils.d(TAG, "readBeanFromJsonReader: 读取新字段 currentBatteryValue 完成"); } else if (name.equals("batteryDetectInterval")) { bean.setBatteryDetectInterval(jsonReader.nextInt()); + } else if (name.equals("defaultFrameWidth")) { + bean.setDefaultFrameWidth(jsonReader.nextInt()); + LogUtils.d(TAG, "readBeanFromJsonReader: 读取字段 defaultFrameWidth 完成"); + } else if (name.equals("defaultFrameHeight")) { + bean.setDefaultFrameHeight(jsonReader.nextInt()); + LogUtils.d(TAG, "readBeanFromJsonReader: 读取字段 defaultFrameHeight 完成"); } else { jsonReader.skipValue(); LogUtils.w(TAG, String.format("readBeanFromJsonReader: 跳过未知字段 %s", name)); @@ -250,6 +297,9 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable dest.writeByte((byte) (isCharging ? 1 : 0)); dest.writeInt(currentBatteryValue); dest.writeInt(batteryDetectInterval); + // 新增相框配置字段写入 + dest.writeInt(defaultFrameWidth); + dest.writeInt(defaultFrameHeight); LogUtils.d(TAG, "writeToParcel: Parcel 序列化完成"); } @@ -267,6 +317,9 @@ public class AppConfigBean extends BaseBean implements Serializable, Parcelable bean.isCharging = source.readByte() != 0; bean.currentBatteryValue = source.readInt(); bean.batteryDetectInterval = source.readInt(); + // 新增相框配置字段读取 + bean.defaultFrameWidth = source.readInt(); + bean.defaultFrameHeight = source.readInt(); LogUtils.d(TAG, "createFromParcel: Parcel 反序列化完成"); return bean; } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java index 041e9b7..4124879 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java @@ -96,7 +96,7 @@ public class AppConfigUtils { /** * 保存应用配置(内部核心方法,直接持久化) */ - private void saveAppConfig() { + public void saveAppConfig() { AppConfigBean.saveBean(mContext, mAppConfigBean); LogUtils.d(TAG, "saveAppConfig:应用配置保存成功"); } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/ImageUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/ImageUtils.java index c7d9f2b..50f7e82 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/ImageUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/ImageUtils.java @@ -6,9 +6,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.graphics.Paint; -import android.view.ViewGroup; -import android.widget.LinearLayout; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.R; import java.io.File; @@ -19,20 +18,24 @@ import java.io.OutputStream; /** * 图片处理工具类(质量压缩专用) - * 功能:对图片进行JPEG质量压缩,并将压缩结果覆盖源文件;获取主题colorPrimary颜色值 + * 功能:1. 图片JPEG质量压缩(覆盖源文件);2. 获取主题colorAccent颜色;3. 位图纯色背景合成 * 适配:Java 7 + Android API 30 - * 核心逻辑:Bitmap.compress 质量压缩 + FileChannel 高效文件复制;主题属性解析 + * 核心逻辑: + * - 压缩:Bitmap.compress + FileChannel 高效文件复制 + * - 主题颜色:TypedArray 解析主题属性 + * - 位图合成:Canvas 绘制(支持透明通道) * @Author 豆包&ZhanGSKen */ public class ImageUtils { + // ================================== 静态常量区(置顶归类,消除魔法值)================================= public static final String TAG = "ImageUtils"; private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.JPEG; private static final int MIN_COMPRESS_QUALITY = 0; private static final int MAX_COMPRESS_QUALITY = 100; - private static final int[] COLOR_ACCENT_ATTR = new int[]{R.attr.colorAccent}; // colorPrimary属性数组 + private static final int[] COLOR_ACCENT_ATTR = new int[]{R.attr.colorAccent}; // colorAccent属性数组 - // ================================== 新增:Accent 颜色获取方法 ================================= + // ================================== 主题颜色获取方法 ================================= /** * 从当前应用主题中获取 colorAccent 颜色值 * @param context 上下文,用于获取主题与资源 @@ -40,14 +43,15 @@ public class ImageUtils { */ public static int getColorAccent(Context context) { LogUtils.d(TAG, "【getColorAccent】方法调用"); + // 参数校验 if (context == null) { - LogUtils.e(TAG, "【getColorAccent】参数异常:Context为空,返回默认颜色"); + LogUtils.e(TAG, "【getColorAccent】参数异常:Context为空"); return Color.parseColor("#FFFFFFFF"); } TypedArray typedArray = null; try { - // 从当前主题中解析 colorAccent 属性 + // 从主题解析属性 typedArray = context.obtainStyledAttributes(COLOR_ACCENT_ATTR); int colorAccent = typedArray.getColor(0, Color.parseColor("#FFFFFFFF")); LogUtils.d(TAG, String.format("【getColorAccent】解析成功 | colorAccent=0x%08X", colorAccent)); @@ -56,15 +60,21 @@ public class ImageUtils { LogUtils.e(TAG, "【getColorAccent】解析失败,返回默认颜色", e); return Color.parseColor("#FFFFFFFF"); } finally { - // 回收TypedArray资源,避免内存泄漏 + // 回收资源 if (typedArray != null) { typedArray.recycle(); LogUtils.d(TAG, "【getColorAccent】TypedArray资源已回收"); } } } - + + public static Bitmap drawBitmapOnSolidBackground(final int bgColor, int originalFrameW, int originalFrameH, Bitmap fgBitmap) { + // 方法调用及入参日志 + LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】方法调用 | 背景色=0x%08X | 目标尺寸=%dx%d | 前景位图=%s", + bgColor, originalFrameW, originalFrameH, + (fgBitmap != null ? fgBitmap.getWidth() + "x" + fgBitmap.getHeight() : "null"))); + // 1. 严格参数校验 if (fgBitmap == null || fgBitmap.isRecycled()) { LogUtils.e(TAG, "【drawBitmapOnSolidBackground】参数异常:前景Bitmap为空或已回收"); @@ -79,49 +89,55 @@ public class ImageUtils { return null; } - // 计算原画框宽高比(核心:返回位图尺寸严格为originalFrameW×originalFrameH,比例自然一致) - float frameRatio = (float) originalFrameW / originalFrameH; - LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】原画框目标尺寸=%dx%d | 画框比例=%.2f", - originalFrameW, originalFrameH, frameRatio)); + // 2. 强制画布尺寸为目标尺寸 + int canvasW = originalFrameW; + int canvasH = originalFrameH; + LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】画布尺寸已确定:%dx%d", canvasW, canvasH)); - // 3. 核心逻辑:强制画布尺寸为originalFrameW×originalFrameH(满足需求) - int extendedCanvasW = originalFrameW; - int extendedCanvasH = originalFrameH; - LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】画布尺寸(强制目标尺寸)=%dx%d | 实际比例=%.2f(与画框一致)", - extendedCanvasW, extendedCanvasH, (float) extendedCanvasW / extendedCanvasH)); - - // 4. 创建与目标尺寸完全一致的结果Bitmap(ARGB_8888 格式支持透明通道) - Bitmap resultBitmap = Bitmap.createBitmap(extendedCanvasW, extendedCanvasH, Bitmap.Config.ARGB_8888); + // 3. 创建结果位图(ARGB_8888支持透明通道) + Bitmap resultBitmap = Bitmap.createBitmap(canvasW, canvasH, Bitmap.Config.ARGB_8888); if (resultBitmap == null) { LogUtils.e(TAG, "【drawBitmapOnSolidBackground】创建结果Bitmap失败"); return null; } - LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】结果Bitmap尺寸=%dx%d | 比例=%.2f", - resultBitmap.getWidth(), resultBitmap.getHeight(), (float) resultBitmap.getWidth() / resultBitmap.getHeight())); - // 5. 画布绘制:先画满纯色背景,再画带透明的居中前景 + // 4. 画布绘制 Canvas canvas = new Canvas(resultBitmap); try { - // 5.1 绘制纯色背景(填满整个目标尺寸画布) - canvas.drawRect(0, 0, extendedCanvasW, extendedCanvasH, new Paint() {{ - setColor(bgColor); - setStyle(Paint.Style.FILL); - }}); - LogUtils.d(TAG, "【drawBitmapOnSolidBackground】纯色背景绘制完成(填满目标尺寸)"); + // 4.1 绘制纯色背景 + Paint bgPaint = new Paint(); + bgPaint.setColor(bgColor); + bgPaint.setStyle(Paint.Style.FILL); + canvas.drawRect(0, 0, canvasW, canvasH, bgPaint); - // 5.2 计算前景在目标画布内的居中位置 - float fgX = (extendedCanvasW - fgBitmap.getWidth()) / 2f; - float fgY = (extendedCanvasH - fgBitmap.getHeight()) / 2f; + // 4.2 计算前景 FIT_CENTER 变换参数(等比缩放至完全放入画布,居中显示) + float fgWidth = fgBitmap.getWidth(); + float fgHeight = fgBitmap.getHeight(); + float scaleX = (float) canvasW / fgWidth; + float scaleY = (float) canvasH / fgHeight; + float scale = Math.min(scaleX, scaleY); // 取最小比例,保证完全放入画布 - // 5.3 绘制前景位图(开启透明度支持,保留Alpha通道) -// Paint fgPaint = new Paint(); -// fgPaint.setAlpha(0); // 保持前景自身透明度(默认255,可根据需求调整) -// fgPaint.setAntiAlias(true); // 可选:抗锯齿,让边缘更平滑 -// fgPaint.setDither(true); // 可选:抖动,提升色彩显示效果 -// canvas.drawBitmap(fgBitmap, fgX, fgY, fgPaint); -// LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】前景位图居中完成 | 位置=(%.1f,%.1f)", -// fgX, fgY)); -// + // 4.3 计算缩放后前景尺寸 + float scaledW = fgWidth * scale; + float scaledH = fgHeight * scale; + + // 4.4 计算居中位置(缩放后居中,无裁剪) + float translateX = (canvasW - scaledW) / 2f; + float translateY = (canvasH - scaledH) / 2f; + + // 4.5 构建变换矩阵(缩放+平移,实现 FIT_CENTER 效果) + Matrix matrix = new Matrix(); + matrix.postScale(scale, scale); // 等比缩放 + matrix.postTranslate(translateX, translateY); // 居中平移 + + // 4.6 绘制前景(保留透明通道,抗锯齿) + Paint fgPaint = new Paint(); + fgPaint.setAntiAlias(true); + fgPaint.setDither(true); + canvas.drawBitmap(fgBitmap, matrix, fgPaint); + + LogUtils.d(TAG, String.format("【drawBitmapOnSolidBackground】合成成功 | 缩放比例=%.2f | 居中位置=(%.1f,%.1f) | 效果=FIT_CENTER", + scale, translateX, translateY)); return resultBitmap; } catch (Exception e) { LogUtils.e(TAG, "【drawBitmapOnSolidBackground】合成失败", e); @@ -132,18 +148,20 @@ public class ImageUtils { } } - - // ================================== 核心工具方法(图片质量压缩)================================= + + // ================================== 核心压缩方法 ================================= /** * 图片质量压缩(JPEG格式),压缩后覆盖源文件 - * @param context 上下文(备用,当前逻辑未直接使用) + * @param context 上下文(备用) * @param srcImagePath 源图片文件路径(非空,文件需存在) - * @param dstImagePath 压缩后临时保存路径(非空,用于存储压缩中间文件) + * @param dstImagePath 压缩后临时保存路径(非空) * @param compressQuality 压缩质量(0-100,数值越小压缩率越高) */ public static void bitmapCompress(Context context, String srcImagePath, String dstImagePath, int compressQuality) { - LogUtils.d(TAG, String.format("【bitmapCompress】调用开始 | 源路径=%s | 临时路径=%s | 压缩质量=%d", + // 方法调用及入参日志 + LogUtils.d(TAG, String.format("【bitmapCompress】方法调用 | 源路径=%s | 临时路径=%s | 压缩质量=%d", srcImagePath, dstImagePath, compressQuality)); + // 1. 前置参数校验 if (srcImagePath == null || srcImagePath.isEmpty()) { LogUtils.e(TAG, "【bitmapCompress】参数异常:源文件路径为空"); @@ -176,7 +194,7 @@ public class ImageUtils { LogUtils.d(TAG, String.format("【bitmapCompress】Bitmap解码成功 | 尺寸=%dx%d", compressBitmap.getWidth(), compressBitmap.getHeight())); - // 3. 创建临时压缩文件 + // 3. 创建临时压缩文件目录 File dstFile = new File(dstImagePath); File dstParentDir = dstFile.getParentFile(); if (dstParentDir != null && !dstParentDir.exists()) { @@ -204,7 +222,7 @@ public class ImageUtils { } catch (IOException e) { LogUtils.e(TAG, "【bitmapCompress】IO异常", e); } finally { - // 6. 资源释放:关闭输出流 + // 6. 关闭输出流 if (outputStream != null) { try { outputStream.close(); @@ -212,7 +230,7 @@ public class ImageUtils { LogUtils.e(TAG, "【bitmapCompress】输出流关闭失败", e); } } - // 7. 资源释放:回收Bitmap + // 7. 回收Bitmap if (compressBitmap != null && !compressBitmap.isRecycled()) { compressBitmap.recycle(); LogUtils.d(TAG, "【bitmapCompress】Bitmap资源已回收"); diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java index c5d20d6..dd3d7e9 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java @@ -9,68 +9,69 @@ import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; + +import java.io.File; + import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.models.BackgroundBean; +import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.ImageUtils; -import java.io.File; /** * 基于Java7的BackgroundView(LinearLayout+ImageView,保持原图比例居中平铺) * 核心:ImageView保持原图比例,在LinearLayout中居中平铺,无拉伸、无裁剪、无压缩 * 改进:强制保持缓存策略,无论内存是否紧张,不自动清理任何缓存,保留图片原始品质 + * @Author 豆包&ZhanGSKen */ public class BackgroundView extends RelativeLayout { - // ====================================== 静态常量区 ====================================== + // ====================================== 静态常量区(首屏可见,统一管理) ====================================== public static final String TAG = "BackgroundView"; // Bitmap 配置常量(原始品质) private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int BITMAP_SAMPLE_SIZE = 1; // 不缩放采样率 - // ====================================== 成员变量区 ====================================== - // 缓存相关 - private String mCurrentCachedPath = ""; - // 视图相关 + // ====================================== 成员变量区(按功能分类:上下文→视图→缓存→图片属性) ====================================== + // 上下文 private Context mContext; - private LinearLayout mLlContainer; // 主容器LinearLayout - private ImageView mIvBackground; // 图片显示控件 + // 视图组件 + private LinearLayout mLlContainer; // 主容器LinearLayout + private ImageView mIvBackground; // 图片显示控件 + // 缓存相关 + private String mCurrentCachedPath = "";// 当前缓存图片路径 // 图片属性 - private float mImageAspectRatio = 1.0f; // 原图宽高比(宽/高) - // 当前图片背景 - private int mbgColor = 0xFFFFFFFF; - // 当前背景画框尺寸 - ViewGroup.LayoutParams mbgLayoutParams; + private float mImageAspectRatio = 1.0f;// 原图宽高比(宽/高) + private int mBgColor = 0xFFFFFFFF; // 当前图片背景色 - // ====================================== 构造器(Java7兼容) ====================================== + // ====================================== 构造器(Java7兼容,按参数重载顺序排列) ====================================== public BackgroundView(Context context) { super(context); - LogUtils.d(TAG, "=== BackgroundView 构造器1启动 [context] ==="); + LogUtils.d(TAG, "BackgroundView() 构造器1启动 | context=" + context.getClass().getSimpleName()); this.mContext = context; initView(); } public BackgroundView(Context context, AttributeSet attrs) { super(context, attrs); - LogUtils.d(TAG, "=== BackgroundView 构造器2启动 [context, attrs] ==="); + LogUtils.d(TAG, "BackgroundView(Context, AttributeSet) 构造器2启动 | context=" + context.getClass().getSimpleName()); this.mContext = context; initView(); } public BackgroundView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - LogUtils.d(TAG, "=== BackgroundView 构造器3启动 [context, attrs, defStyleAttr] ==="); + LogUtils.d(TAG, "BackgroundView(Context, AttributeSet, int) 构造器3启动 | context=" + context.getClass().getSimpleName()); this.mContext = context; initView(); } - // ====================================== 初始化方法 ====================================== + // ====================================== 初始化方法(按执行顺序:主视图→子容器→图片控件→默认背景) ====================================== private void initView() { - LogUtils.d(TAG, "=== initView 启动 ==="); + LogUtils.d(TAG, "initView() 启动"); // 1. 配置当前控件:全屏+透明 setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); // 2. 初始化主容器LinearLayout @@ -79,11 +80,11 @@ public class BackgroundView extends RelativeLayout { initImageView(); // 4. 初始设置透明背景 setDefaultEmptyBackground(); - LogUtils.d(TAG, "=== initView 完成 ==="); + LogUtils.d(TAG, "initView() 完成"); } private void initLinearLayout() { - LogUtils.d(TAG, "=== initLinearLayout 启动 ==="); + LogUtils.d(TAG, "initLinearLayout() 启动"); mLlContainer = new LinearLayout(mContext); LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, @@ -92,202 +93,133 @@ public class BackgroundView extends RelativeLayout { mLlContainer.setLayoutParams(llParams); mLlContainer.setOrientation(LinearLayout.VERTICAL); mLlContainer.setGravity(android.view.Gravity.CENTER); - //mLlContainer.setBackgroundColor(0x00000000); this.addView(mLlContainer); - LogUtils.d(TAG, "=== initLinearLayout 完成 ==="); + LogUtils.d(TAG, "initLinearLayout() 完成"); } private void initImageView() { - LogUtils.d(TAG, "=== initImageView 启动 ==="); + LogUtils.d(TAG, "initImageView() 启动"); mIvBackground = new ImageView(mContext); LinearLayout.LayoutParams ivParams = new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.MATCH_PARENT + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT ); mIvBackground.setLayoutParams(ivParams); mIvBackground.setScaleType(ImageView.ScaleType.FIT_CENTER); - //mIvBackground.setBackgroundColor(0x00000000); mLlContainer.addView(mIvBackground); - LogUtils.d(TAG, "=== initImageView 完成 ==="); + LogUtils.d(TAG, "initImageView() 完成"); } - // ====================================== 对外方法 ====================================== + // ====================================== 对外公开方法(按功能分类:Bean加载→图片加载) ====================================== public void loadByBackgroundBean(BackgroundBean bean) { loadByBackgroundBean(bean, false); } public void loadByBackgroundBean(BackgroundBean bean, boolean isRefresh) { - LogUtils.d(TAG, "=== loadByBackgroundBean 启动 [isRefresh:" + isRefresh + "] ==="); + LogUtils.d(TAG, String.format("loadByBackgroundBean() 启动 | isRefresh=%b | bean=%s", isRefresh, bean)); // 参数校验 if (bean == null) { - LogUtils.e(TAG, "loadByBackgroundBean: BackgroundBean为空"); + LogUtils.e(TAG, "loadByBackgroundBean() 异常:BackgroundBean为空"); setDefaultEmptyBackground(); return; } - // 设置图片背景 - mbgColor = bean.getPixelColor(); + // 设置图片背景色 + mBgColor = bean.getPixelColor(); // 判断是否使用背景文件 if (!bean.isUseBackgroundFile()) { - LogUtils.d(TAG, "loadByBackgroundBean: 不使用背景文件,设置透明背景"); + LogUtils.d(TAG, "loadByBackgroundBean() 不使用背景文件,设置透明背景"); setDefaultEmptyBackground(); return; } + // 获取目标路径 String targetPath = bean.isUseBackgroundScaledCompressFile() ? bean.getBackgroundScaledCompressFilePath() : bean.getBackgroundFilePath(); - LogUtils.d(TAG, "loadByBackgroundBean: 目标路径=" + targetPath); + LogUtils.d(TAG, String.format("loadByBackgroundBean() 目标路径=%s", targetPath)); + // 校验文件是否存在 File targetFile = new File(targetPath); if (!targetFile.exists() || !targetFile.isFile()) { - LogUtils.e(TAG, "loadByBackgroundBean: 视图控件图片不存在:" + targetPath); + LogUtils.e(TAG, "loadByBackgroundBean() 异常:图片文件不存在 | path=" + targetPath); return; } - loadImage(mbgColor, targetPath, isRefresh); + + loadImage(mBgColor, targetPath, isRefresh); } - - public void loadImage(int bgColor, String imagePath, boolean isRefresh) { - // 3. 隐藏ImageView防止闪烁 - mIvBackground.setVisibility(View.GONE); - // 计算画框尺寸 - //mbgLayoutParams = adjustImageViewSize(); - mbgLayoutParams = mLlContainer.getLayoutParams(); + + public void loadImage(int bgColor, String imagePath, boolean isRefresh) { + LogUtils.d(TAG, String.format("loadImage() 启动 | bgColor=0x%08X | imagePath=%s | isRefresh=%b", bgColor, imagePath, isRefresh)); + // 隐藏ImageView防止闪烁 + mIvBackground.setVisibility(View.GONE); + + // 初始化配置工具类并保存默认相框尺寸 + AppConfigUtils appConfigUtils = AppConfigUtils.getInstance(mContext); + appConfigUtils.loadAppConfig(); + if (getWidth() > 0 && getHeight() > 0) { + appConfigUtils.mAppConfigBean.setDefaultFrameWidth(getWidth()); + appConfigUtils.mAppConfigBean.setDefaultFrameHeight(getHeight()); + appConfigUtils.saveAppConfig(); + LogUtils.d(TAG, String.format("loadImage() 保存默认相框尺寸 | width=%d | height=%d", getWidth(), getHeight())); + } // 刷新逻辑:重新解码原始品质图片并更新缓存 if (isRefresh) { - LogUtils.d(TAG, "loadByBackgroundBean: 刷新图片,重新解码原始品质图片并更新缓存"); + LogUtils.d(TAG, "loadImage() 执行刷新逻辑:重新解码原始品质图片"); Bitmap newBitmap = decodeOriginalBitmap(new File(imagePath)); + // 合成纯色背景图片 +// Bitmap combinedBitmap = ImageUtils.drawBitmapOnSolidBackground(bgColor, +// appConfigUtils.mAppConfigBean.getDefaultFrameWidth(), +// appConfigUtils.mAppConfigBean.getDefaultFrameHeight(), +// newBitmap); + Bitmap combinedBitmap = ImageUtils.drawBitmapOnSolidBackground(bgColor, + 1197, + 2287, + newBitmap); + + if (combinedBitmap == null) { + ToastUtils.show("合成背景图片失败,使用原始图片"); + LogUtils.e(TAG, "loadImage() 纯色背景合成失败,使用原始Bitmap"); + combinedBitmap = newBitmap; + } else { + ToastUtils.show("合成背景图片成功"); + LogUtils.d(TAG, "loadImage() 纯色背景合成成功"); + // 回收原始Bitmap(避免重复缓存) + if (newBitmap != null && !newBitmap.isRecycled() && newBitmap != combinedBitmap) { + newBitmap.recycle(); + LogUtils.d(TAG, "loadImage() 原始Bitmap已回收"); + } + } - // ======================== 核心集成:调用drawBitmapOnSolidBackground合成 ======================== - //Bitmap combinedBitmap = ImageUtils.drawBitmapOnSolidBackground(mbgColor, mbgLayoutParams.width, mbgLayoutParams.height, newBitmap); - Bitmap combinedBitmap = ImageUtils.drawBitmapOnSolidBackground(0xFF112233, mbgLayoutParams.width, mbgLayoutParams.height, newBitmap); - if (combinedBitmap == null) { - LogUtils.e(TAG, "loadImage: 纯色背景合成失败,使用原始Bitmap"); - combinedBitmap = newBitmap; - } else { - LogUtils.d(TAG, "loadImage: 纯色背景合成成功,尺寸与原始图一致"); - // 合成成功后,回收原始Bitmap(避免重复缓存) - if (newBitmap != null && !newBitmap.isRecycled() && newBitmap != combinedBitmap) { - newBitmap.recycle(); - LogUtils.d(TAG, "loadImage: 原始Bitmap已回收"); - } - } - // ======================== 合成逻辑结束 ======================== + // 更新缓存 if (combinedBitmap != null) { - App.sBitmapCacheUtils.clearAllCache(); App.sBitmapCacheUtils.cacheBitmap(imagePath, combinedBitmap); App.sBitmapCacheUtils.increaseRefCount(imagePath); - mCurrentCachedPath = imagePath; - LogUtils.d(TAG, "loadByBackgroundBean: 刷新缓存成功,路径=" + imagePath); + mCurrentCachedPath = imagePath; + LogUtils.d(TAG, String.format("loadImage() 刷新缓存成功 | path=%s", imagePath)); } else { - LogUtils.e(TAG, "loadByBackgroundBean: 刷新解码失败,路径=" + imagePath); + LogUtils.e(TAG, String.format("loadImage() 刷新解码失败 | path=%s", imagePath)); } } - // 加载图片 - Bitmap cachedBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath); -// LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mIvBackground.getLayoutParams(); -// params.width = mbgLayoutParams.width; -// params.height = mbgLayoutParams.height; -// mIvBackground.setLayoutParams(params); -// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( -// LinearLayout.LayoutParams.MATCH_PARENT, -// LinearLayout.LayoutParams.MATCH_PARENT -// ); - //mIvBackground.setLayoutParams(params); + // 加载缓存图片 + Bitmap cachedBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath); mIvBackground.setImageBitmap(cachedBitmap); - mIvBackground.setScaleType(ImageView.ScaleType.FIT_CENTER); + mIvBackground.setScaleType(ImageView.ScaleType.FIT_CENTER); mIvBackground.setVisibility(View.VISIBLE); - LogUtils.d(TAG, "=== loadByBackgroundBean 完成 ==="); - } + LogUtils.d(TAG, "loadImage() 完成"); + } - /** - * 改进版:强制保持缓存策略,不自动清理任何缓存,强化引用计数管理,保留图片原始品质 - * @param imagePath 图片绝对路径 - */ -// public void loadImage2(String imagePath) { -// LogUtils.d(TAG, "=== loadImage 启动,路径:" + imagePath + ",背景色:0x%08X ===", mbgColor); -// // 1. 路径空校验 -// if (TextUtils.isEmpty(imagePath)) { -// LogUtils.e(TAG, "loadImage: 图片路径为空"); -// setDefaultEmptyBackground(); -// return; -// } -// // 2. 文件有效性校验 -// File imageFile = new File(imagePath); -// if (!imageFile.exists() || !imageFile.isFile()) { -// LogUtils.e(TAG, "loadImage: 图片文件无效"); -// setDefaultEmptyBackground(); -// return; -// } -// -// // ======================== 路径判断逻辑(强制缓存版) ======================== -// // 3.1 路径未变化:校验缓存有效性(缓存的是合成后的Bitmap) -// if (imagePath.equals(mCurrentCachedPath)) { -// Bitmap cachedBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath); -// if (isBitmapValid(cachedBitmap)) { -// LogUtils.d(TAG, "loadImage: 路径未变,使用有效缓存Bitmap(合成后品质)"); -// mImageAspectRatio = (float) cachedBitmap.getWidth() / cachedBitmap.getHeight(); -// mIvBackground.setImageBitmap(cachedBitmap); -// mIvBackground.setVisibility(View.VISIBLE); -// LogUtils.d(TAG, "=== loadImage 完成(缓存命中) ==="); -// return; -// } else { -// LogUtils.e(TAG, "loadImage: 缓存Bitmap无效,尝试重加载并合成"); -// } -// } -// // 3.2 路径已更新:保留旧缓存,仅更新路径记录 -// if (!TextUtils.isEmpty(mCurrentCachedPath) && !mCurrentCachedPath.equals(imagePath)) { -// LogUtils.d(TAG, "loadImage: 路径已更新,保留旧缓存,原路径=" + mCurrentCachedPath + ",新路径=" + imagePath); -// } -// // ======================== 路径判断逻辑结束 ======================== -// -// // 4. 计算图片宽高比(原始图片) -// if (!calculateImageAspectRatio(imageFile)) { -// setDefaultEmptyBackground(); -// return; -// } -// -// -// // 5. 获取或解码Bitmap(原始图) -// Bitmap originalBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath); -// if (isBitmapValid(originalBitmap)) { -// LogUtils.d(TAG, "loadImage: 从缓存获取原始Bitmap,准备合成"); -// } else { -// LogUtils.d(TAG, "loadImage: 缓存未命中,解码原始品质图片"); -// originalBitmap = decodeOriginalBitmap(imageFile); -// if (originalBitmap == null) { -// LogUtils.e(TAG, "loadImage: 图片解码失败(原始品质)"); -// ToastUtils.show("图片解码失败,无法加载"); -// setDefaultEmptyBackground(); -// return; -// } -// } -// -// // 6. 缓存合成后的Bitmap(替换原始图缓存) -//// App.sBitmapCacheUtils.cacheBitmap(imagePath, originalBitmap); -//// LogUtils.d(TAG, "loadImage: 合成后图片缓存成功,路径=" + imagePath); -//// // 7. 引用计数管理 -//// App.sBitmapCacheUtils.increaseRefCount(imagePath); -// // 8. 更新当前缓存路径 -// mCurrentCachedPath = imagePath; -// // 9. 设置图片并调整尺寸 -// //mIvBackground.setImageBitmap(originalBitmap); -// -// LogUtils.d(TAG, "=== loadImage 完成(合成后加载) ==="); -// } - - - // ====================================== 内部工具方法 ====================================== + // ====================================== 内部工具方法(按功能分类:Bitmap校验→比例计算→解码→背景设置) ====================================== /** * 工具方法:判断Bitmap是否有效(非空且未被回收) */ private boolean isBitmapValid(Bitmap bitmap) { boolean valid = bitmap != null && !bitmap.isRecycled(); if (!valid) { - LogUtils.w(TAG, "isBitmapValid: Bitmap无效(空或已回收)"); + LogUtils.w(TAG, "isBitmapValid() 无效:Bitmap为空或已回收"); } return valid; } @@ -296,25 +228,26 @@ public class BackgroundView extends RelativeLayout { * 计算图片宽高比 */ private boolean calculateImageAspectRatio(File file) { - LogUtils.d(TAG, "=== calculateImageAspectRatio 启动,文件=" + file.getAbsolutePath() + " ==="); + LogUtils.d(TAG, String.format("calculateImageAspectRatio() 启动 | file=%s", file.getAbsolutePath())); try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); + // 尺寸校验 int width = options.outWidth; int height = options.outHeight; if (width <= 0 || height <= 0) { - LogUtils.e(TAG, "calculateImageAspectRatio: 图片尺寸无效,宽=" + width + ",高=" + height); + LogUtils.e(TAG, String.format("calculateImageAspectRatio() 无效尺寸 | width=%d | height=%d", width, height)); return false; } + // 计算比例 mImageAspectRatio = (float) width / height; - LogUtils.d(TAG, "calculateImageAspectRatio: 原图比例=" + mImageAspectRatio); - LogUtils.d(TAG, "=== calculateImageAspectRatio 完成 ==="); + LogUtils.d(TAG, String.format("calculateImageAspectRatio() 完成 | 比例=%.2f", mImageAspectRatio)); return true; } catch (Exception e) { - LogUtils.e(TAG, "calculateImageAspectRatio: 计算比例失败:" + e.getMessage()); + LogUtils.e(TAG, "calculateImageAspectRatio() 失败:" + e.getMessage()); return false; } } @@ -323,7 +256,7 @@ public class BackgroundView extends RelativeLayout { * 移除压缩逻辑:解码原始品质图片(无缩放、无色彩损失) */ private Bitmap decodeOriginalBitmap(File file) { - LogUtils.d(TAG, "=== decodeOriginalBitmap 启动,文件=" + file.getAbsolutePath() + " ==="); + LogUtils.d(TAG, String.format("decodeOriginalBitmap() 启动 | file=%s", file.getAbsolutePath())); try { BitmapFactory.Options options = new BitmapFactory.Options(); // 核心配置:原始品质 @@ -333,84 +266,40 @@ public class BackgroundView extends RelativeLayout { options.inInputShareable = false; options.inDither = true; options.inScaled = false; + // 解码图片 Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options); if (bitmap != null) { - LogUtils.d(TAG, "decodeOriginalBitmap: 解码成功,宽=" + bitmap.getWidth() + ",高=" + bitmap.getHeight()); + LogUtils.d(TAG, String.format("decodeOriginalBitmap() 成功 | width=%d | height=%d", bitmap.getWidth(), bitmap.getHeight())); } else { - LogUtils.e(TAG, "decodeOriginalBitmap: 解码返回null"); + LogUtils.e(TAG, "decodeOriginalBitmap() 失败:返回null"); } - LogUtils.d(TAG, "=== decodeOriginalBitmap 完成 ==="); return bitmap; } catch (Exception e) { - LogUtils.e(TAG, "decodeOriginalBitmap: 原始品质解码失败:" + e.getMessage()); + LogUtils.e(TAG, "decodeOriginalBitmap() 异常:" + e.getMessage()); return null; } } - /** - * 调整ImageView尺寸,保持原图比例 - */ -// private LinearLayout.LayoutParams adjustImageViewSize() { -// LogUtils.d(TAG, "=== adjustImageViewSize 启动 ==="); -// // 空指针校验 -// if (mLlContainer == null || mIvBackground == null) { -// LogUtils.e(TAG, "adjustImageViewSize: 容器或ImageView未初始化"); -// return null; -// } -// // 获取容器尺寸 -// int llWidth = mLlContainer.getWidth(); -// int llHeight = mLlContainer.getHeight(); -// if (llWidth == 0 || llHeight == 0) { -// LogUtils.w(TAG, "adjustImageViewSize: 容器尺寸未初始化,延迟调整"); -// post(new Runnable() { -// @Override -// public void run() { -// adjustImageViewSize(); -// } -// }); -// return null; -// } -// // 计算ImageView尺寸 -// int ivWidth, ivHeight; -// if (mImageAspectRatio >= 1.0f) { -// ivWidth = Math.min((int) (llHeight * mImageAspectRatio), llWidth); -// ivHeight = (int) (ivWidth / mImageAspectRatio); -// } else { -// ivHeight = Math.min((int) (llWidth / mImageAspectRatio), llHeight); -// ivWidth = (int) (ivHeight * mImageAspectRatio); -// } -// // 设置尺寸 -// LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mIvBackground.getLayoutParams(); -// params.width = ivWidth; -// params.height = ivHeight; -// mIvBackground.setLayoutParams(params); -// mIvBackground.setScaleType(ImageView.ScaleType.FIT_CENTER); -// mIvBackground.setVisibility(View.VISIBLE); -// LogUtils.d(TAG, "adjustImageViewSize: 尺寸调整完成,宽=" + ivWidth + ",高=" + ivHeight); -// LogUtils.d(TAG, "=== adjustImageViewSize 完成 ==="); -// return params; -// } - /** * 设置默认透明背景,仅减少引用计数,不删除缓存 */ private void setDefaultEmptyBackground() { - LogUtils.d(TAG, "=== setDefaultTransparentBackground 启动 ==="); + LogUtils.d(TAG, "setDefaultEmptyBackground() 启动"); // 清空ImageView mIvBackground.setImageDrawable(null); - //mIvBackground.setBackgroundColor(mbgColor); mImageAspectRatio = 1.0f; + // 减少引用计数,不删除缓存 if (!TextUtils.isEmpty(mCurrentCachedPath)) { - LogUtils.d(TAG, "setDefaultTransparentBackground: 减少引用计数,路径=" + mCurrentCachedPath); + LogUtils.d(TAG, String.format("setDefaultEmptyBackground() 减少引用计数 | path=%s", mCurrentCachedPath)); App.sBitmapCacheUtils.decreaseRefCount(mCurrentCachedPath); mCurrentCachedPath = ""; } - LogUtils.d(TAG, "=== setDefaultTransparentBackground 完成 ==="); + LogUtils.d(TAG, "setDefaultEmptyBackground() 完成"); } - // ====================================== 重写生命周期方法 ====================================== + // ====================================== 重写生命周期方法(按执行顺序:绘制→尺寸变化→窗口分离) ====================================== /** * 重写:绘制前强制校验Bitmap有效性,防止已回收Bitmap崩溃 */ @@ -421,7 +310,7 @@ public class BackgroundView extends RelativeLayout { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; Bitmap bitmap = bitmapDrawable.getBitmap(); if (!isBitmapValid(bitmap)) { - LogUtils.e(TAG, "onDraw: 检测到已回收Bitmap,清空本地绘制(保留全局缓存)"); + LogUtils.e(TAG, "onDraw() 检测到已回收Bitmap,清空绘制"); mIvBackground.setImageDrawable(null); return; } @@ -429,34 +318,32 @@ public class BackgroundView extends RelativeLayout { super.onDraw(canvas); } - /** - * 重写:View从窗口移除时仅减少引用计数,不删除全局缓存(强制保持策略) - */ - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - LogUtils.d(TAG, "=== onDetachedFromWindow 启动 ==="); - // 清空ImageView的Drawable,释放本地引用 - mIvBackground.setImageDrawable(null); - // 减少引用计数,不删除全局缓存 - if (!TextUtils.isEmpty(mCurrentCachedPath)) { - LogUtils.d(TAG, "onDetachedFromWindow: 减少引用计数,路径=" + mCurrentCachedPath); - App.sBitmapCacheUtils.decreaseRefCount(mCurrentCachedPath); - mCurrentCachedPath = ""; - } - LogUtils.d(TAG, "=== onDetachedFromWindow 完成 ==="); - } - /** * 重写:恢复尺寸调整逻辑,确保View尺寸变化时正确显示(无压缩) */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - LogUtils.d(TAG, "onSizeChanged: 尺寸变化,宽=" + w + ",高=" + h + ",调整ImageView尺寸"); - //adjustImageViewSize(); -// mbgLayoutParams.width = mLlContainer.getWidth(); -// mbgLayoutParams.height = mLlContainer.getHeight(); + LogUtils.d(TAG, String.format("onSizeChanged() 尺寸变化 | newW=%d | newH=%d | oldW=%d | oldH=%d", w, h, oldw, oldh)); + } + + /** + * 重写:View从窗口移除时仅减少引用计数,不删除全局缓存(强制保持策略) + */ + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + LogUtils.d(TAG, "onDetachedFromWindow() 启动"); + // 清空ImageView的Drawable,释放本地引用 + mIvBackground.setImageDrawable(null); + + // 减少引用计数,不删除全局缓存 + if (!TextUtils.isEmpty(mCurrentCachedPath)) { + LogUtils.d(TAG, String.format("onDetachedFromWindow() 减少引用计数 | path=%s", mCurrentCachedPath)); + App.sBitmapCacheUtils.decreaseRefCount(mCurrentCachedPath); + mCurrentCachedPath = ""; + } + LogUtils.d(TAG, "onDetachedFromWindow() 完成"); } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/MemoryCachedBackgroundView.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/MemoryCachedBackgroundView.java index 699c864..be810fe 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/MemoryCachedBackgroundView.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/MemoryCachedBackgroundView.java @@ -7,14 +7,15 @@ import android.util.AttributeSet; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.models.BackgroundBean; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; +import cc.winboll.studio.powerbell.App; +import cc.winboll.studio.powerbell.utils.AppConfigUtils; /** * 单实例缓存版背景视图控件(基于Java7)- 强制缓存版 * 核心:通过静态属性保存当前缓存路径和实例,支持强制重载图片 * 新增:SP持久化最后加载路径、获取最后加载实例功能 * 强制缓存策略:无论内存是否紧张,不自动清理任何缓存实例和路径记录 - * @Author ZhanGSKen&豆包大模型 - * @Date 2025/12/21 20:43 + * @Author 豆包&ZhanGSKen */ public class MemoryCachedBackgroundView extends BackgroundView { // ====================================== 静态常量区(TAG + SP相关常量) ====================================== @@ -34,19 +35,19 @@ public class MemoryCachedBackgroundView extends BackgroundView { private MemoryCachedBackgroundView(Context context) { super(context); sInstanceCount++; - LogUtils.d(TAG, "【构造器1】创建MemoryCachedBackgroundView实例,当前实例总数:" + sInstanceCount); + LogUtils.d(TAG, String.format("构造器1启动 | 创建实例,当前实例总数=%d", sInstanceCount)); } private MemoryCachedBackgroundView(Context context, AttributeSet attrs) { super(context, attrs); sInstanceCount++; - LogUtils.d(TAG, "【构造器2】创建MemoryCachedBackgroundView实例,当前实例总数:" + sInstanceCount); + LogUtils.d(TAG, String.format("构造器2启动 | 创建实例,当前实例总数=%d", sInstanceCount)); } private MemoryCachedBackgroundView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); sInstanceCount++; - LogUtils.d(TAG, "【构造器3】创建MemoryCachedBackgroundView实例,当前实例总数:" + sInstanceCount); + LogUtils.d(TAG, String.format("构造器3启动 | 创建实例,当前实例总数=%d", sInstanceCount)); } // ====================================== 核心静态方法:获取/创建缓存实例(强制缓存版) ====================================== @@ -58,32 +59,32 @@ public class MemoryCachedBackgroundView extends BackgroundView { * @return 缓存/新创建的MemoryCachedBackgroundView实例 */ public static MemoryCachedBackgroundView getInstance(Context context, int bgColor, String imagePath, boolean isReload) { - LogUtils.d(TAG, "【getInstance】调用 | 图片路径:" + imagePath + " | 是否重载:" + isReload); + LogUtils.d(TAG, String.format("getInstance 调用 | 图片路径=%s | 是否重载=%b", imagePath, isReload)); // 空路径校验 if (TextUtils.isEmpty(imagePath)) { - LogUtils.e(TAG, "【getInstance】图片路径为空,创建空实例"); + LogUtils.e(TAG, "getInstance: 图片路径为空,创建空实例"); return new MemoryCachedBackgroundView(context); } // 1. 路径匹配缓存 → 判断是否强制重载 if (imagePath.equals(sCachedImagePath) && sCachedView != null) { - LogUtils.d(TAG, "【getInstance】路径已缓存,当前缓存实例有效"); + LogUtils.d(TAG, "getInstance: 路径已缓存,当前缓存实例有效"); if (isReload) { - LogUtils.d(TAG, "【getInstance】强制重载图片 | 路径:" + imagePath); + LogUtils.d(TAG, String.format("getInstance: 强制重载图片 | 路径=%s", imagePath)); sCachedView.loadImage(bgColor, imagePath, isReload); } else { - LogUtils.d(TAG, "【getInstance】使用缓存实例,无需重载 | 路径:" + imagePath); + LogUtils.d(TAG, String.format("getInstance: 使用缓存实例,无需重载 | 路径=%s", imagePath)); } return sCachedView; } // 2. 路径不匹配/无缓存 → 新建实例并更新静态缓存(核心:保留旧实例,仅更新引用) - LogUtils.d(TAG, "【getInstance】路径未缓存,新建实例(保留旧实例) | 路径:" + imagePath); + LogUtils.d(TAG, String.format("getInstance: 路径未缓存,新建实例(保留旧实例) | 路径=%s", imagePath)); String oldPath = sCachedImagePath; sCachedView = new MemoryCachedBackgroundView(context); sCachedImagePath = imagePath; sCachedView.loadImage(bgColor, imagePath, isReload); - LogUtils.d(TAG, "【getInstance】已更新当前缓存实例,旧实例路径:" + oldPath + "(强制保持)"); + LogUtils.d(TAG, String.format("getInstance: 已更新当前缓存实例,旧实例路径=%s(强制保持)", oldPath)); return sCachedView; } @@ -95,28 +96,28 @@ public class MemoryCachedBackgroundView extends BackgroundView { * @return 最后加载路径对应的实例 */ public static MemoryCachedBackgroundView getLastInstance(Context context) { - LogUtils.d(TAG, "【getLastInstance】调用"); + LogUtils.d(TAG, "getLastInstance 调用"); // 1. 从SP获取最后加载的路径(强制保持,不自动删除) String lastPath = getLastLoadImagePath(context); if (TextUtils.isEmpty(lastPath)) { - LogUtils.e(TAG, "【getLastInstance】无最后加载路径,创建空实例"); + LogUtils.e(TAG, "getLastInstance: 无最后加载路径,创建空实例"); return new MemoryCachedBackgroundView(context); } // 2. 路径匹配当前缓存 → 直接返回 if (lastPath.equals(sCachedImagePath) && sCachedView != null) { - LogUtils.d(TAG, "【getLastInstance】使用最后路径缓存实例 | 路径:" + lastPath); + LogUtils.d(TAG, String.format("getLastInstance: 使用最后路径缓存实例 | 路径=%s", lastPath)); return sCachedView; } // 3. 路径不匹配 → 新建实例并更新缓存(保留旧实例) - LogUtils.d(TAG, "【getLastInstance】最后路径未缓存,新建实例并加载(保留旧实例) | 路径:" + lastPath); + LogUtils.d(TAG, String.format("getLastInstance: 最后路径未缓存,新建实例并加载(保留旧实例) | 路径=%s", lastPath)); String oldPath = sCachedImagePath; sCachedView = new MemoryCachedBackgroundView(context); sCachedImagePath = lastPath; - int nCurrentPixelColor = BackgroundSourceUtils.getInstance(context).getCurrentBackgroundBean().getPixelColor(); - sCachedView.loadImage(nCurrentPixelColor, sCachedImagePath, false); - LogUtils.d(TAG, "【getLastInstance】已更新最后路径实例,旧实例路径:" + oldPath + "(强制保持)"); + int nCurrentPixelColor = BackgroundSourceUtils.getInstance(context).getCurrentBackgroundBean().getPixelColor(); + sCachedView.loadImage(nCurrentPixelColor, sCachedImagePath, false); + LogUtils.d(TAG, String.format("getLastInstance: 已更新最后路径实例,旧实例路径=%s(强制保持)", oldPath)); return sCachedView; } @@ -128,12 +129,12 @@ public class MemoryCachedBackgroundView extends BackgroundView { */ private static void saveLastLoadImagePath(Context context, String imagePath) { if (TextUtils.isEmpty(imagePath) || context == null) { - LogUtils.w(TAG, "【saveLastLoadImagePath】路径或上下文为空,跳过保存"); + LogUtils.w(TAG, "saveLastLoadImagePath: 路径或上下文为空,跳过保存"); return; } SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); sp.edit().putString(KEY_LAST_LOAD_IMAGE_PATH, imagePath).apply(); - LogUtils.d(TAG, "【saveLastLoadImagePath】已保存最后路径(强制保持) | 路径:" + imagePath); + LogUtils.d(TAG, String.format("saveLastLoadImagePath: 已保存最后路径(强制保持) | 路径=%s", imagePath)); } /** @@ -143,12 +144,12 @@ public class MemoryCachedBackgroundView extends BackgroundView { */ public static String getLastLoadImagePath(Context context) { if (context == null) { - LogUtils.e(TAG, "【getLastLoadImagePath】上下文为空,返回null"); + LogUtils.e(TAG, "getLastLoadImagePath: 上下文为空,返回null"); return null; } SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); String lastPath = sp.getString(KEY_LAST_LOAD_IMAGE_PATH, null); - LogUtils.d(TAG, "【getLastLoadImagePath】获取最后路径(强制保持) | 路径:" + lastPath); + LogUtils.d(TAG, String.format("getLastLoadImagePath: 获取最后路径(强制保持) | 路径=%s", lastPath)); return lastPath; } @@ -157,8 +158,8 @@ public class MemoryCachedBackgroundView extends BackgroundView { * 清除当前缓存实例和路径(强制缓存策略:仅日志,不实际清理) */ public static void clearCache() { - LogUtils.w(TAG, "【clearCache】调用(强制缓存策略:不实际清理缓存) | 当前缓存路径:" + sCachedImagePath); - LogUtils.d(TAG, "【clearCache】强制缓存策略生效,未清除任何实例和路径"); + LogUtils.w(TAG, String.format("clearCache 调用(强制缓存策略:不实际清理缓存) | 当前缓存路径=%s", sCachedImagePath)); + LogUtils.d(TAG, "clearCache: 强制缓存策略生效,未清除任何实例和路径"); } /** @@ -166,20 +167,20 @@ public class MemoryCachedBackgroundView extends BackgroundView { * @param imagePath 图片路径 */ public static void removeCache(String imagePath) { - LogUtils.w(TAG, "【removeCache】调用(强制缓存策略:不实际清理缓存) | 图片路径:" + imagePath); + LogUtils.w(TAG, String.format("removeCache 调用(强制缓存策略:不实际清理缓存) | 图片路径=%s", imagePath)); if (TextUtils.isEmpty(imagePath)) { - LogUtils.e(TAG, "【removeCache】图片路径为空,清除失败"); + LogUtils.e(TAG, "removeCache: 图片路径为空,清除失败"); return; } - LogUtils.d(TAG, "【removeCache】强制缓存策略生效,未清除任何实例和路径"); + LogUtils.d(TAG, "removeCache: 强制缓存策略生效,未清除任何实例和路径"); } /** * 清除所有缓存(强制缓存策略:仅日志,不实际清理) */ public static void clearAllCache() { - LogUtils.w(TAG, "【clearAllCache】调用(强制缓存策略:不实际清理缓存)"); - LogUtils.d(TAG, "【clearAllCache】强制缓存策略生效,未清除任何实例、路径和SP记录"); + LogUtils.w(TAG, "clearAllCache 调用(强制缓存策略:不实际清理缓存)"); + LogUtils.d(TAG, "clearAllCache: 强制缓存策略生效,未清除任何实例、路径和SP记录"); } /** @@ -188,7 +189,7 @@ public class MemoryCachedBackgroundView extends BackgroundView { */ public static boolean hasCache() { boolean hasCache = sCachedView != null && !TextUtils.isEmpty(sCachedImagePath); - LogUtils.d(TAG, "【hasCache】缓存存在状态:" + hasCache); + LogUtils.d(TAG, String.format("hasCache 调用 | 缓存存在状态=%b", hasCache)); return hasCache; } @@ -197,8 +198,8 @@ public class MemoryCachedBackgroundView extends BackgroundView { * @param context 上下文 */ public static void clearLastLoadImagePath(Context context) { - LogUtils.w(TAG, "【clearLastLoadImagePath】调用(强制缓存策略:不实际清理SP记录)"); - LogUtils.d(TAG, "【clearLastLoadImagePath】强制缓存策略生效,未清除SP中最后路径记录"); + LogUtils.w(TAG, "clearLastLoadImagePath 调用(强制缓存策略:不实际清理SP记录)"); + LogUtils.d(TAG, "clearLastLoadImagePath: 强制缓存策略生效,未清除SP中最后路径记录"); } // ====================================== 辅助方法:从缓存获取上下文 ====================================== @@ -208,28 +209,20 @@ public class MemoryCachedBackgroundView extends BackgroundView { */ private static Context getContextFromCache() { Context context = sCachedView != null ? sCachedView.getContext() : null; - LogUtils.d(TAG, "【getContextFromCache】从缓存获取上下文:" + context); + LogUtils.d(TAG, String.format("getContextFromCache 调用 | 从缓存获取上下文=%s", context)); return context; } // ====================================== 重写父类方法:增强日志+SP持久化(强制保持版) ====================================== -// @Override -// public void loadImage(String imagePath) { -// LogUtils.d(TAG, "【loadImage】调用 | 图片路径:" + imagePath); -// super.loadImage(imagePath); -// // 保存最后加载路径到SP(强制保持,不自动删除) -// saveLastLoadImagePath(getContext(), imagePath); -// } - @Override public void loadByBackgroundBean(BackgroundBean bean) { - LogUtils.d(TAG, "【loadByBackgroundBean】调用 | BackgroundBean:" + (bean == null ? "null" : bean.toString())); + LogUtils.d(TAG, String.format("loadByBackgroundBean 调用 | BackgroundBean=%s", (bean == null ? "null" : bean.toString()))); super.loadByBackgroundBean(bean); } @Override public void loadByBackgroundBean(BackgroundBean bean, boolean isRefresh) { - LogUtils.d(TAG, "【loadByBackgroundBean】调用 | BackgroundBean:" + (bean == null ? "null" : bean.toString()) + " | 是否刷新:" + isRefresh); + LogUtils.d(TAG, String.format("loadByBackgroundBean 调用 | BackgroundBean=%s | 是否刷新=%b", (bean == null ? "null" : bean.toString()), isRefresh)); super.loadByBackgroundBean(bean, isRefresh); } @@ -239,7 +232,7 @@ public class MemoryCachedBackgroundView extends BackgroundView { * @return 实例总数 */ public static int getInstanceCount() { - LogUtils.d(TAG, "【getInstanceCount】调用 | 当前实例总数:" + sInstanceCount); + LogUtils.d(TAG, String.format("getInstanceCount 调用 | 当前实例总数=%d", sInstanceCount)); return sInstanceCount; } }