diff --git a/powerbell/build.properties b/powerbell/build.properties index 8f59695..47c0c5b 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed Dec 10 18:38:00 HKT 2025 +#Wed Dec 10 11:21:09 GMT 2025 stageCount=10 libraryProject= baseVersion=15.12 publishVersion=15.12.9 -buildCount=0 +buildCount=4 baseBetaVersion=15.12.10 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 aa35596..2398300 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java @@ -15,6 +15,7 @@ import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.ViewStub; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; @@ -24,6 +25,7 @@ import android.widget.SeekBar; import android.widget.Switch; import android.widget.TextView; import androidx.appcompat.widget.Toolbar; + import cc.winboll.studio.libaes.activitys.AboutActivity; import cc.winboll.studio.libaes.models.APPInfo; import cc.winboll.studio.libaes.utils.AESThemeUtil; @@ -49,68 +51,73 @@ import cc.winboll.studio.powerbell.views.BatteryDrawable; import cc.winboll.studio.powerbell.views.VerticalSeekBar; /** - * 主活动类(修复小米广告SDK空Context崩溃问题) - * 核心修改点: - * 1. 添加全局Context安全校验 - * 2. 优化广告请求的生命周期判断 - * 3. 确保广告操作在主线程执行 - * 4. 完善广告资源释放逻辑 + * 主活动类(Java 7 兼容 | 首屏加速改造:视图缓存+懒加载) + * 核心优化点(解决首次启动慢): + * 1. ViewHolder 缓存控件,避免首次多次 findViewById + * 2. ViewStub 延迟加载非首屏关键视图(广告、次要布局) + * 3. 核心视图预加载+资源异步加载 + * 4. 非关键任务(服务检查、数据初始化)异步化 + * 5. 减少首次启动时的同步 inflate 耗时 + * 修复点:解决首次加载图片失败问题(背景图+电量图标) */ public class MainActivity extends WinBoLLActivity { // ======================== 静态常量(首屏排列,统一管理)======================== public static final String TAG = "MainActivity"; private static final int REQUEST_WRITE_STORAGE_PERMISSION = 1001; - - // ======================== 成员属性(按「静态→非静态」「核心→辅助」排序)======================== - public static MainActivity _mMainActivity; // 静态Activity实例(全局调用) - private App mApplication; // 应用Application实例 - private Menu mMenu; // 顶部菜单实例 - private Fragment mCurrentShowFragment; // 当前显示的Fragment - private MainViewFragment mMainViewFragment; // 主Fragment(核心视图) - private Toolbar mToolbar; // 顶部工具栏 - private ADsBannerView mADsBannerView; // 广告Banner视图 - - public static final int MSG_RELOAD_APPCONFIG = 0; + public static final int MSG_RELOAD_APPCONFIG = 0; public static final int MSG_CURRENTVALUEBATTERY = 1; + public static final int MSG_LOAD_BACKGROUND = 2; // 新增:背景图片加载消息 + private static final int DELAY_LOAD_NON_CRITICAL = 500; // 非关键视图延迟加载时间(500ms) + // ======================== 成员属性(按「静态→非静态」「核心→辅助」排序,ViewHolder 优先)======================== + // 全局静态引用(控制生命周期) + public static MainActivity _mMainActivity; static MainViewFragment _mMainViewFragment; - AppConfigUtils mAppConfigUtils; - Drawable mDrawableFrame; - LinearLayout mllLeftSeekBar; - LinearLayout mllRightSeekBar; - CheckBox mcbIsEnableChargeReminder; - CheckBox mcbIsEnableUsegeReminder; - Switch mswIsEnableService; - TextView mtvTips; + static Handler _mHandler; - private BackgroundSourceUtils mBgSourceUtils; + // 核心工具类(提前初始化,避免首次同步耗时) + private App mApplication; + private AppConfigUtils mAppConfigUtils; + private BackgroundSourceUtils mBgSourceUtils; - // 背景布局 - //LinearLayout mLinearLayoutloadBackground; + // 顶部导航与广告(非首屏核心,用ViewStub延迟加载) + private Toolbar mToolbar; + private ViewStub mAdsViewStub; // 广告视图占位符(首次不加载) + private ADsBannerView mADsBannerView; - // 现在电量图示 - BatteryDrawable mCurrentValueBatteryDrawable; - // 现在充电提醒电量图示 - BatteryDrawable mChargeReminderValueBatteryDrawable; - // 现在耗电提醒电量图示 - BatteryDrawable mUsegeReminderValueBatteryDrawable; + // 视图缓存核心:ViewHolder(一次性绑定所有控件,避免多次findViewById) + private ViewHolder mViewHolder; - ImageView mCurrentValueBatteryImageView; - ImageView mChargeReminderValueBatteryImageView; - ImageView mUsegeReminderValueBatteryImageView; - - VerticalSeekBar mChargeReminderSeekBar; - ChargeReminderSeekBarChangeListener mChargeReminderSeekBarChangeListener; - TextView mtvChargeReminderValue; + // 其他辅助属性 + private Menu mMenu; + private Fragment mCurrentShowFragment; + private MainViewFragment mMainViewFragment; + private Drawable mDrawableFrame; + // 电量图示(首次初始化耗时,放入ViewHolder缓存) + private BatteryDrawable mCurrentValueBatteryDrawable; + private BatteryDrawable mChargeReminderValueBatteryDrawable; + private BatteryDrawable mUsegeReminderValueBatteryDrawable; - VerticalSeekBar mUsegeReminderSeekBar; - UsegeReminderSeekBarChangeListener mUsegeReminderSeekBarChangeListener; - TextView mtvUsegeReminderValue; - CheckBox mcbUsegeReminderValue; - TextView mtvCurrentValue; - BackgroundView mBackgroundView; + // ======================== 视图缓存容器(ViewHolder 模式,Java 7 兼容)======================== + /** + * ViewHolder 静态内部类:一次性绑定所有控件,缓存实例 + * 避免首次启动时多次调用 findViewById(遍历视图树耗时),仅在首次 inflate 后绑定一次 + */ + private static class ViewHolder { + // 首屏核心视图(必须优先加载) + BackgroundView backgroundView; // 背景视图(首屏关键,图片加载核心) + RelativeLayout mainLayout; // 主布局(设置背景色,首屏关键) + + // 电量控制核心控件(首屏必须显示) + LinearLayout llLeftSeekBar, llRightSeekBar; + CheckBox cbIsEnableChargeReminder, cbIsEnableUsegeReminder; + Switch swIsEnableService; + TextView tvTips, tvChargeReminderValue, tvUsegeReminderValue, tvCurrentValue; + VerticalSeekBar chargeReminderSeekBar, usegeReminderSeekBar; + ImageView ivCurrentBattery, ivChargeReminderBattery, ivUsegeReminderBattery; + } // ======================== 重写父类抽象方法(优先排列,明确实现)======================== @@ -126,36 +133,57 @@ public class MainActivity extends WinBoLLActivity { @Override protected void onCreate(Bundle savedInstanceState) { - LogUtils.d(TAG, "onCreate(...)"); + LogUtils.d(TAG, "onCreate(...) - 首屏加速改造(Java 7 兼容)- 修复图片加载"); super.onCreate(savedInstanceState); + // 关键优化2:提前初始化全局Handler(避免首次使用时创建耗时,Java 7 简化写法) + initGlobalHandler(); + + // 1. 快速加载布局(仅加载首屏核心视图,非核心用ViewStub占位) setContentView(R.layout.activity_main); - // 初始化视图与实例 - initView(); - initInstance(); -// initFragment(); + // 2. 初始化核心工具类(异步初始化,避免阻塞主线程,Java 7 线程创建方式) + initCoreUtilsAsync(); - // 权限申请 + // 3. 初始化ViewHolder(一次性绑定所有控件,缓存实例,核心加速点) + initViewHolder(); + + // 4. 初始化首屏核心视图(必须同步加载,保证首屏显示) + initCriticalView(); + + // 5. 延迟加载非首屏核心视图(广告、次要控件,首屏渲染后再加载) + loadNonCriticalViewDelayed(); + + // 6. 权限申请(轻量操作,同步执行) PermissionUtils.getInstance().checkAndRequestStoragePermission(this); } @Override protected void onDestroy() { super.onDestroy(); - // 释放广告资源 + // 释放资源,避免内存泄漏 if (mADsBannerView != null) { mADsBannerView.releaseAdResources(); } - // 置空静态引用,避免内存泄漏 + // 置空静态引用 _mMainActivity = null; + _mMainViewFragment = null; + // 移除Handler回调(Java 7 兼容) + if (_mHandler != null) { + _mHandler.removeCallbacksAndMessages(null); + } } @Override protected void onResume() { super.onResume(); - reloadBackground(); - setBackgroundColor(); - // 恢复广告 + // 修复1:移除此处背景刷新(避免工具类未初始化完成时调用,导致图片加载失败) + // reloadBackground(); + // setBackgroundColor(); + // 改为:发送消息让Handler控制加载时机(确保工具类已初始化) + if (_mHandler != null) { + _mHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND); + } + // 非核心:恢复广告(仅在首次延迟加载后执行) if (mADsBannerView != null) { mADsBannerView.resumeADs(MainActivity.this); } @@ -164,13 +192,13 @@ public class MainActivity extends WinBoLLActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { mMenu = menu; - // 主题菜单 + // 主题菜单(轻量,同步加载) AESThemeUtil.inflateMenu(this, menu); - // 调试工具菜单(仅Debug模式显示) + // 调试菜单(仅Debug模式,轻量) if (App.isDebugging()) { DevelopUtils.inflateMenu(this, menu); } - // 应用核心菜单 + // 应用核心菜单(轻量,同步加载) getMenuInflater().inflate(R.menu.toolbar_main, mMenu); return true; } @@ -178,17 +206,17 @@ public class MainActivity extends WinBoLLActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { int menuItemId = item.getItemId(); - // 主题切换菜单 + // 主题切换 if (AESThemeUtil.onAppThemeItemSelected(this, item)) { recreate(); return true; } - // 调试工具菜单 + // 调试工具 if (DevelopUtils.onDevelopItemSelected(this, item)) { LogUtils.d(TAG, String.format("onOptionsItemSelected item.getItemId() %d ", item.getItemId())); return true; } - // 应用核心菜单 + // 应用核心菜单(Java 7 用switch,移除Lambda) switch (menuItemId) { case R.id.action_settings: startActivity(new Intent(this, SettingsActivity.class)); @@ -220,15 +248,17 @@ public class MainActivity extends WinBoLLActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); + // 修复2:背景图片选择后刷新(确保图片更新) + if (resultCode == Activity.RESULT_OK) { + if (_mHandler != null) { + _mHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND); + } + } } @Override public void onBackPressed() { - if (mCurrentShowFragment != mMainViewFragment) { - showFragment(mMainViewFragment); - } else { - moveTaskToBack(true); - } + moveTaskToBack(true); } @Override @@ -245,48 +275,44 @@ public class MainActivity extends WinBoLLActivity { } - // ======================== 核心业务逻辑方法(按功能优先级排序)======================== + // ======================== 核心业务逻辑方法(按功能优先级排序,Java 7 兼容)======================== /** - * 显示指定Fragment(隐藏其他Fragment) + * 刷新背景(仅执行必要操作,避免首次耗时) */ - void showFragment(Fragment fragment) { - FragmentTransaction tx = getFragmentManager().beginTransaction(); - for (Fragment item : getFragmentManager().getFragments()) { - tx.hide(item); - } - tx.show(fragment); - tx.commit(); - mCurrentShowFragment = fragment; - } - - /** - * 刷新背景(全局静态调用,带生命周期校验) - */ -// public static void reloadBackground() { -// if (_mMainActivity != null && !_mMainActivity.isFinishing() && !_mMainActivity.isDestroyed()) { -// _mMainActivity.mMainViewFragment.reloadBackground(); -// } -// } - - /** - * 设置主页面背景颜色(从BackgroundBean获取颜色值) - */ - void setBackgroundColor() { - // 生命周期校验,避免Activity销毁后操作UI - if (isFinishing() || isDestroyed()) { + public void reloadBackground() { + // 修复3:增加多重判空(避免工具类/视图未初始化导致空指针,图片加载失败) + if (mViewHolder == null || mBgSourceUtils == null || mViewHolder.backgroundView == null) { + LogUtils.e(TAG, "reloadBackground: 背景加载失败(控件/工具类未初始化)"); return; } - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - BackgroundBean bean = utils.getCurrentBackgroundBean(); - int nPixelColor = bean.getPixelColor(); - RelativeLayout mainLayout = findViewById(R.id.activitymainRelativeLayout1); - if (mainLayout != null) { - mainLayout.setBackgroundColor(nPixelColor); + // 仅加载背景Bean,避免同步执行耗时操作 + BackgroundBean bean = mBgSourceUtils.getCurrentBackgroundBean(); + if (bean != null) { + mViewHolder.backgroundView.loadBackgroundBean(bean); + } else { + LogUtils.e(TAG, "reloadBackground: 背景Bean为空(图片路径异常)"); + // 容错:加载默认背景图(避免空白) + mViewHolder.backgroundView.setBackgroundResource(R.drawable.default_background); } } /** - * 通过Uri获取文件本地真实路径(兼容图片选择等场景) + * 设置主页面背景颜色(首屏关键,同步执行但轻量化) + */ + void setBackgroundColor() { + if (isFinishing() || isDestroyed() || mViewHolder == null || mBgSourceUtils == null || mViewHolder.mainLayout == null) { + return; + } + // 轻量化操作:仅获取颜色值并设置,避免额外耗时 + BackgroundBean bean = mBgSourceUtils.getCurrentBackgroundBean(); + if (bean != null) { + int nPixelColor = bean.getPixelColor(); + mViewHolder.mainLayout.setBackgroundColor(nPixelColor); + } + } + + /** + * 通过Uri获取文件本地真实路径(按需加载,不影响首屏) */ private String getRealPathFromURI(Uri contentUri) { String[] proj = {MediaStore.MediaColumns.DATA}; @@ -297,8 +323,6 @@ public class MainActivity extends WinBoLLActivity { String path = cursor.getString(nColumnIndex); cursor.close(); return path; - } else { - LogUtils.d(TAG, "getRealPathFromURI nColumnIndex is -1."); } cursor.close(); } @@ -306,7 +330,7 @@ public class MainActivity extends WinBoLLActivity { } /** - * 生成默认APP信息(用于关于页面) + * 生成默认APP信息(按需加载,不影响首屏) */ APPInfo genDefaultAPPInfo() { String szBranchName = "powerbell"; @@ -324,218 +348,354 @@ public class MainActivity extends WinBoLLActivity { return appInfo; } - - // ======================== 内部初始化辅助方法(私有,统一放在最后)======================== /** - * 初始化视图控件(findViewById) + * 设置视图数据(首屏核心,同步执行但轻量化) */ - private void initView() { - mAppConfigUtils = App.getAppConfigUtils(getActivity()); - mBgSourceUtils = BackgroundSourceUtils.getInstance(getActivity()); - - mADsBannerView = findViewById(R.id.adsbanner); - mToolbar = findViewById(R.id.toolbar); + void setViewData() { + if (mViewHolder == null || mAppConfigUtils == null) return; - // 获取指定ID的View实例 - mBackgroundView = findViewById(R.id.fragmentmainviewBackgroundView1); - - loadBackground(); - /*final View mainImageView = mView.findViewById(R.id.fragmentmainviewImageView1); - - // 注册OnGlobalLayoutListener - mainImageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - // 获取宽度和高度 - int width = mainImageView.getMeasuredWidth(); - int height = mainImageView.getMeasuredHeight(); - - BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(getActivity()); - BackgroundPictureBean bean = utils.loadBackgroundPictureBean(); - bean.setBackgroundWidth(width); - bean.setBackgroundHeight(height); - utils.saveData(); - // 移除监听器以避免内存泄漏 - mainImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } - });*/ - - mDrawableFrame = getActivity().getDrawable(R.drawable.bg_frame); - mllLeftSeekBar = (LinearLayout) findViewById(R.id.fragmentmainviewLinearLayout1); - mllRightSeekBar = (LinearLayout) findViewById(R.id.fragmentmainviewLinearLayout2); - - // 初始化充电电量提醒设置控件 - mtvChargeReminderValue = (TextView) findViewById(R.id.fragmentandroidviewTextView2); - mChargeReminderSeekBar = (VerticalSeekBar) findViewById(R.id.fragmentandroidviewVerticalSeekBar1); - mcbIsEnableChargeReminder = findViewById(R.id.fragmentmainviewCheckBox1); - - // 初始化耗电电量提醒设置控件 - mtvUsegeReminderValue = (TextView) findViewById(R.id.fragmentandroidviewTextView3); - mUsegeReminderSeekBar = (VerticalSeekBar) findViewById(R.id.fragmentandroidviewVerticalSeekBar2); - mcbIsEnableUsegeReminder = findViewById(R.id.fragmentmainviewCheckBox2); - - // 初始化现在电量显示控件 - mtvCurrentValue = (TextView) findViewById(R.id.fragmentandroidviewTextView4); - - // 初始化服务总开关 - mswIsEnableService = (Switch) findViewById(R.id.fragmentandroidviewSwitch1); - mtvTips = findViewById(R.id.fragmentandroidviewTextView1); - - // 设置视图显示数据 - setViewData(); - // 设置视图控件响应 - setViewListener(); - - // 注册一个广播接收 - //mMainActivityReceiver = new MainActivityReceiver(this); - //mMainActivityReceiver.registerAction(); - - // 启动的时候检查一下服务 - if (mAppConfigUtils.getIsEnableService() - && ServiceUtils.isServiceAlive(getActivity(), ControlCenterService.class.getName()) == false) { - // 如果配置了服务启动,服务没有启动 - // 就启动服务 - Intent intent = new Intent(getActivity(), ControlCenterService.class); - getActivity().startForegroundService(intent); - } - } - - void loadBackground() { - BackgroundBean bean = mBgSourceUtils.getCurrentBackgroundBean(); - mBackgroundView.loadBackgroundBean(bean); - } - - void setViewData() { int nChargeReminderValue = mAppConfigUtils.getChargeReminderValue(); int nUsegeReminderValue = mAppConfigUtils.getUsegeReminderValue(); int nCurrentValue = mAppConfigUtils.getCurrentValue(); - mllLeftSeekBar.setBackground(mDrawableFrame); - mllRightSeekBar.setBackground(mDrawableFrame); - - // 初始化电量图 - mCurrentValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorCurrent)); - mCurrentValueBatteryDrawable.setValue(mAppConfigUtils.getCurrentValue()); - mCurrentValueBatteryImageView = findViewById(R.id.fragmentandroidviewImageView1); - mCurrentValueBatteryImageView.setImageDrawable(mCurrentValueBatteryDrawable); - - // 初始化充电电量提醒图 - mChargeReminderValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorCharge)); - mChargeReminderValueBatteryDrawable.setValue(nChargeReminderValue); - mChargeReminderValueBatteryImageView = findViewById(R.id.fragmentandroidviewImageView3); - mChargeReminderValueBatteryImageView.setImageDrawable(mChargeReminderValueBatteryDrawable); - - // 初始化耗电电量提醒图 - mUsegeReminderValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorUsege)); - mUsegeReminderValueBatteryDrawable.setValue(nUsegeReminderValue); - mUsegeReminderValueBatteryImageView = findViewById(R.id.fragmentandroidviewImageView2); - mUsegeReminderValueBatteryImageView.setImageDrawable(mUsegeReminderValueBatteryDrawable); - - // 初始化充电电量提醒设置控件 - mtvChargeReminderValue.setTextColor(getActivity().getColor(R.color.colorCharge)); - //LogUtils.d(TAG, "Color.YELLOW is " + Integer.toString(mApplication.getColor(R.color.colorCharge))); - mtvChargeReminderValue.setText(Integer.toString(nChargeReminderValue) + "%"); - mChargeReminderSeekBar.setProgress(nChargeReminderValue); - mcbIsEnableChargeReminder.setChecked(mAppConfigUtils.getIsEnableChargeReminder()); - - // 初始化耗电电量提醒设置控件 - mtvUsegeReminderValue.setTextColor(getActivity().getColor(R.color.colorUsege)); - mtvUsegeReminderValue.setText(Integer.toString(nUsegeReminderValue) + "%"); - mUsegeReminderSeekBar.setProgress(nUsegeReminderValue); - mcbIsEnableUsegeReminder.setChecked(mAppConfigUtils.getIsEnableUsegeReminder()); - - // 初始化现在电量显示控件 - mtvCurrentValue.setTextColor(getActivity().getColor(R.color.colorCurrent)); - mtvCurrentValue.setText(Integer.toString(nCurrentValue) + "%"); - - // 初始化服务总开关 - mswIsEnableService.setChecked(mAppConfigUtils.getIsEnableService()); - if (mAppConfigUtils.getIsEnableService()) { - //LogUtils.d(TAG, "mApplication.getIsEnableService() " + Boolean.toString(mAppConfigUtils.getIsEnableService())); - ControlCenterService.startControlCenterService(getActivity()); - } else { - //LogUtils.d(TAG, "mApplication.getIsEnableService() " + Boolean.toString(mAppConfigUtils.getIsEnableService())); - ControlCenterService.stopControlCenterService(getActivity()); + // 轻量化设置:仅绑定必要数据,避免复杂计算 + if (mViewHolder.llLeftSeekBar != null && mViewHolder.llRightSeekBar != null && mDrawableFrame != null) { + mViewHolder.llLeftSeekBar.setBackground(mDrawableFrame); + mViewHolder.llRightSeekBar.setBackground(mDrawableFrame); } - mswIsEnableService.setText(getString(R.string.txt_aboveswitch)); - mtvTips.setText(getString(R.string.txt_aboveswitchtips)); + // 电量图示初始化(首次耗时,缓存实例) + // 修复4:电量图标判空容错(避免控件未绑定导致图片加载失败) + if (mViewHolder.ivCurrentBattery != null) { + if (mCurrentValueBatteryDrawable == null) { + mCurrentValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorCurrent)); + } + mCurrentValueBatteryDrawable.setValue(nCurrentValue); + mViewHolder.ivCurrentBattery.setImageDrawable(mCurrentValueBatteryDrawable); + } + + if (mViewHolder.ivChargeReminderBattery != null) { + if (mChargeReminderValueBatteryDrawable == null) { + mChargeReminderValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorCharge)); + } + mChargeReminderValueBatteryDrawable.setValue(nChargeReminderValue); + mViewHolder.ivChargeReminderBattery.setImageDrawable(mChargeReminderValueBatteryDrawable); + } + + if (mViewHolder.ivUsegeReminderBattery != null) { + if (mUsegeReminderValueBatteryDrawable == null) { + mUsegeReminderValueBatteryDrawable = new BatteryDrawable(getActivity().getColor(R.color.colorUsege)); + } + mUsegeReminderValueBatteryDrawable.setValue(nUsegeReminderValue); + mViewHolder.ivUsegeReminderBattery.setImageDrawable(mUsegeReminderValueBatteryDrawable); + } + + // 控件数据绑定(轻量化) + if (mViewHolder.tvChargeReminderValue != null) { + mViewHolder.tvChargeReminderValue.setTextColor(getActivity().getColor(R.color.colorCharge)); + mViewHolder.tvChargeReminderValue.setText(String.valueOf(nChargeReminderValue) + "%"); + } + if (mViewHolder.chargeReminderSeekBar != null) { + mViewHolder.chargeReminderSeekBar.setProgress(nChargeReminderValue); + } + if (mViewHolder.cbIsEnableChargeReminder != null) { + mViewHolder.cbIsEnableChargeReminder.setChecked(mAppConfigUtils.getIsEnableChargeReminder()); + } + + if (mViewHolder.tvUsegeReminderValue != null) { + mViewHolder.tvUsegeReminderValue.setTextColor(getActivity().getColor(R.color.colorUsege)); + mViewHolder.tvUsegeReminderValue.setText(String.valueOf(nUsegeReminderValue) + "%"); + } + if (mViewHolder.usegeReminderSeekBar != null) { + mViewHolder.usegeReminderSeekBar.setProgress(nUsegeReminderValue); + } + if (mViewHolder.cbIsEnableUsegeReminder != null) { + mViewHolder.cbIsEnableUsegeReminder.setChecked(mAppConfigUtils.getIsEnableUsegeReminder()); + } + + if (mViewHolder.tvCurrentValue != null) { + mViewHolder.tvCurrentValue.setTextColor(getActivity().getColor(R.color.colorCurrent)); + mViewHolder.tvCurrentValue.setText(String.valueOf(nCurrentValue) + "%"); + } + + if (mViewHolder.swIsEnableService != null) { + mViewHolder.swIsEnableService.setChecked(mAppConfigUtils.getIsEnableService()); + mViewHolder.swIsEnableService.setText(getString(R.string.txt_aboveswitch)); + } + if (mViewHolder.tvTips != null) { + mViewHolder.tvTips.setText(getString(R.string.txt_aboveswitchtips)); + } } + /** + * 设置视图监听(首屏核心,同步执行但轻量化,Java 7 移除Lambda,用匿名内部类) + */ void setViewListener() { - // 初始化充电电量提醒设置控件 - mChargeReminderSeekBarChangeListener = new ChargeReminderSeekBarChangeListener(); - mChargeReminderSeekBar.setOnSeekBarChangeListener(mChargeReminderSeekBarChangeListener); - mcbIsEnableChargeReminder.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LogUtils.d(TAG, "setIsEnableChargeReminder"); - mAppConfigUtils.setIsEnableChargeReminder(mcbIsEnableChargeReminder.isChecked()); - //ControlCenterService.updateIsEnableChargeReminder(mcbIsEnableChargeReminder.isChecked()); - } - }); + if (mViewHolder == null || mAppConfigUtils == null) return; + // 充电提醒SeekBar监听 + if (mViewHolder.chargeReminderSeekBar != null) { + mViewHolder.chargeReminderSeekBar.setOnSeekBarChangeListener(new ChargeReminderSeekBarChangeListener()); + } + if (mViewHolder.cbIsEnableChargeReminder != null) { + mViewHolder.cbIsEnableChargeReminder.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mAppConfigUtils.setIsEnableChargeReminder(mViewHolder.cbIsEnableChargeReminder.isChecked()); + } + }); + } - // 初始化耗电电量提醒设置控件 - mUsegeReminderSeekBarChangeListener = new UsegeReminderSeekBarChangeListener(); - mUsegeReminderSeekBar.setOnSeekBarChangeListener(mUsegeReminderSeekBarChangeListener); - mcbIsEnableUsegeReminder.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LogUtils.d(TAG, "setIsEnableUsegeReminder"); - mAppConfigUtils.setIsEnableUsegeReminder(mcbIsEnableUsegeReminder.isChecked()); - //ControlCenterService.updateIsEnableUsegeReminder(mcbIsEnableUsegeReminder.isChecked()); - } - }); + // 耗电提醒SeekBar监听 + if (mViewHolder.usegeReminderSeekBar != null) { + mViewHolder.usegeReminderSeekBar.setOnSeekBarChangeListener(new UsegeReminderSeekBarChangeListener()); + } + if (mViewHolder.cbIsEnableUsegeReminder != null) { + mViewHolder.cbIsEnableUsegeReminder.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mAppConfigUtils.setIsEnableUsegeReminder(mViewHolder.cbIsEnableUsegeReminder.isChecked()); + } + }); + } - // 初始化服务总开关 - mswIsEnableService.setOnClickListener(new CompoundButton.OnClickListener() { - - @Override - public void onClick(View view) { - mAppConfigUtils.setIsEnableService(getActivity(), mswIsEnableService.isChecked()); - } - }); + // 服务总开关监听(Java 7 用CompoundButton.OnClickListener匿名内部类) + if (mViewHolder.swIsEnableService != null) { + mViewHolder.swIsEnableService.setOnClickListener(new CompoundButton.OnClickListener() { + @Override + public void onClick(View view) { + mAppConfigUtils.setIsEnableService(getActivity(), mViewHolder.swIsEnableService.isChecked()); + } + }); + } } + /** + * 更新当前电量显示(轻量化,避免耗时) + */ void setCurrentValueBattery(int value) { - //LogUtils.d(TAG, "setCurrentValueBattery"); - mtvCurrentValue.setText(Integer.toString(value) + "%"); + if (mViewHolder == null || mCurrentValueBatteryDrawable == null || mViewHolder.tvCurrentValue == null) return; + mViewHolder.tvCurrentValue.setText(String.valueOf(value) + "%"); mCurrentValueBatteryDrawable.setValue(value); mCurrentValueBatteryDrawable.invalidateSelf(); } + // ======================== 首屏加速核心辅助方法(Java 7 兼容)======================== + /** + * 初始化ViewHolder(核心优化1:一次性绑定所有控件,避免首次多次findViewById) + * 仅在onCreate中执行一次,后续直接复用缓存的控件实例 + */ + private void initViewHolder() { + mViewHolder = new ViewHolder(); + // 一次性绑定所有控件(仅执行一次,减少视图树遍历耗时) + // 修复5:确保控件ID与布局文件完全一致(关键!之前ID匹配无误,增加判空日志) + mViewHolder.mainLayout = (RelativeLayout) findViewById(R.id.activitymainRelativeLayout1); + if (mViewHolder.mainLayout == null) LogUtils.e(TAG, "initViewHolder: mainLayout绑定失败(ID不匹配)"); - public void reloadBackground() { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(getActivity()); - utils.loadSettings(); - BackgroundBean bean = utils.getCurrentBackgroundBean(); - mBackgroundView.loadBackgroundBean(bean); + mViewHolder.backgroundView = (BackgroundView) findViewById(R.id.fragmentmainviewBackgroundView1); + if (mViewHolder.backgroundView == null) LogUtils.e(TAG, "initViewHolder: backgroundView绑定失败(ID不匹配)"); + + mViewHolder.llLeftSeekBar = (LinearLayout) findViewById(R.id.fragmentmainviewLinearLayout1); + mViewHolder.llRightSeekBar = (LinearLayout) findViewById(R.id.fragmentmainviewLinearLayout2); + mViewHolder.cbIsEnableChargeReminder = (CheckBox) findViewById(R.id.fragmentmainviewCheckBox1); + mViewHolder.cbIsEnableUsegeReminder = (CheckBox) findViewById(R.id.fragmentmainviewCheckBox2); + mViewHolder.swIsEnableService = (Switch) findViewById(R.id.fragmentandroidviewSwitch1); + mViewHolder.tvTips = (TextView) findViewById(R.id.fragmentandroidviewTextView1); + mViewHolder.tvChargeReminderValue = (TextView) findViewById(R.id.fragmentandroidviewTextView2); + mViewHolder.tvUsegeReminderValue = (TextView) findViewById(R.id.fragmentandroidviewTextView3); + mViewHolder.tvCurrentValue = (TextView) findViewById(R.id.fragmentandroidviewTextView4); + mViewHolder.chargeReminderSeekBar = (VerticalSeekBar) findViewById(R.id.fragmentandroidviewVerticalSeekBar1); + mViewHolder.usegeReminderSeekBar = (VerticalSeekBar) findViewById(R.id.fragmentandroidviewVerticalSeekBar2); + mViewHolder.ivCurrentBattery = (ImageView) findViewById(R.id.fragmentandroidviewImageView1); + mViewHolder.ivChargeReminderBattery = (ImageView) findViewById(R.id.fragmentandroidviewImageView3); + mViewHolder.ivUsegeReminderBattery = (ImageView) findViewById(R.id.fragmentandroidviewImageView2); + // 广告占位符(首次不加载) + mAdsViewStub = (ViewStub) findViewById(R.id.stub_ads_banner); + // 顶部Toolbar(首屏核心,同步加载) + mToolbar = (Toolbar) findViewById(R.id.toolbar); } - static Handler _mHandler = new Handler(){ + /** + * 初始化核心工具类(异步化,核心优化2:避免首次同步初始化耗时,Java 7 线程创建) + * 工具类初始化(如AppConfigUtils、BackgroundSourceUtils)可能涉及文件读取,异步执行不阻塞首屏 + */ + private void initCoreUtilsAsync() { + new Thread(new Runnable() { + @Override + public void run() { + mApplication = (App) getApplication(); + mAppConfigUtils = App.getAppConfigUtils(getActivity()); + mBgSourceUtils = BackgroundSourceUtils.getInstance(getActivity()); + // 工具类初始化完成后,主线程更新视图数据(避免空指针,Java 7 用runOnUiThread) + runOnUiThread(new Runnable() { + @Override + public void run() { + // 加载背景资源(轻量化) + if (getActivity() != null) { + mDrawableFrame = getActivity().getDrawable(R.drawable.bg_frame); + } + // 设置视图数据和监听(首屏核心,此时工具类已初始化完成) + setViewData(); + setViewListener(); + // 检查服务(非首屏关键,异步执行) + checkServiceAsync(); + // 修复6:工具类初始化完成后,主动加载背景图片(确保首次加载成功) + if (_mHandler != null) { + _mHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND); + } + } + }); + } + }).start(); + } + + /** + * 初始化首屏核心视图(同步执行,保证首屏显示) + * 仅加载必须显示的视图,非核心视图延迟加载 + */ + private void initCriticalView() { + _mMainActivity = this; + // 初始化Toolbar(首屏导航,必须显示) + setSupportActionBar(mToolbar); + if (mToolbar != null) { + mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); + } + // 初始化主Fragment(若启用,同步执行但轻量化) + // initFragment(); + } + + /** + * 延迟加载非首屏核心视图(核心优化3:减少首次启动耗时,Java 7 用Handler.postDelayed) + * 广告、次要布局等非首屏必须的视图,在首屏渲染完成后(500ms)加载 + */ + private void loadNonCriticalViewDelayed() { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (isFinishing() || isDestroyed()) return; + // 加载广告视图(非首屏核心,延迟加载) + loadAdsView(); + // 其他非首屏视图(如调试面板、次要控件)可在此处添加 + } + }, DELAY_LOAD_NON_CRITICAL); + } + + /** + * 加载广告视图(ViewStub 延迟加载,核心优化4:避免首次inflate广告耗时) + * ViewStub 首次inflate时才加载视图,之前仅占占位符资源(轻量) + */ + private void loadAdsView() { + if (mAdsViewStub == null) return; + // 仅首次加载时inflate,后续复用缓存的mADsBannerView + if (mADsBannerView == null) { + View adsView = mAdsViewStub.inflate(); // 延迟inflate,不阻塞首屏 + mADsBannerView = (ADsBannerView) adsView.findViewById(R.id.adsbanner); + } + } + + /** + * 检查服务状态(异步化,核心优化5:避免首次同步检查耗时,Java 7 线程) + * 服务检查涉及进程判断,异步执行不阻塞首屏 + */ + private void checkServiceAsync() { + new Thread(new Runnable() { + @Override + public void run() { + if (mAppConfigUtils == null || isFinishing() || isDestroyed()) return; + // 检查服务是否需要启动 + if (mAppConfigUtils.getIsEnableService() + && !ServiceUtils.isServiceAlive(getActivity(), ControlCenterService.class.getName())) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(getActivity(), ControlCenterService.class); + getActivity().startForegroundService(intent); + } + }); + } + } + }).start(); + } + + /** + * 初始化全局Handler(提前初始化,避免首次使用时创建耗时,Java 7 简化写法) + * 修复7:新增MSG_LOAD_BACKGROUND消息,统一控制背景加载时机(确保工具类+控件都已初始化) + */ + private void initGlobalHandler() { + if (_mHandler == null) { + _mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_RELOAD_APPCONFIG: + if (_mMainActivity != null && _mMainActivity.mViewHolder != null) { + _mMainActivity.setViewData(); + } + break; + case MSG_CURRENTVALUEBATTERY: + if (_mMainActivity != null && _mMainActivity.mViewHolder != null) { + _mMainActivity.setCurrentValueBattery(msg.arg1); + } + break; + case MSG_LOAD_BACKGROUND: // 新增:背景图片加载消息 + if (_mMainActivity != null) { + _mMainActivity.reloadBackground(); // 加载背景图 + _mMainActivity.setBackgroundColor(); // 设置背景色 + } + break; + } + super.handleMessage(msg); + } + }; + } + } + + // ======================== 内部监听类(Java 7 兼容,保持原有逻辑)======================== + class ChargeReminderSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener { @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_RELOAD_APPCONFIG : { - if (_mMainActivity != null) { - _mMainActivity.setViewData(); - } - break; - } - case MSG_CURRENTVALUEBATTERY : { - if (_mMainActivity != null) { - _mMainActivity.setCurrentValueBattery(msg.arg1); - } - break; - } - } - super.handleMessage(msg); + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (mViewHolder == null || mChargeReminderValueBatteryDrawable == null || mViewHolder.tvChargeReminderValue == null) return; + mViewHolder.tvChargeReminderValue.setText(String.valueOf(progress) + "%"); + mChargeReminderValueBatteryDrawable.setValue(progress); + mChargeReminderValueBatteryDrawable.invalidateSelf(); } - }; + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (mAppConfigUtils == null || mViewHolder == null || mViewHolder.tvChargeReminderValue == null) return; + int nChargeReminderValue = ((VerticalSeekBar) seekBar)._mnProgress; + mAppConfigUtils.setChargeReminderValue(nChargeReminderValue); + mViewHolder.tvChargeReminderValue.setText(String.valueOf(nChargeReminderValue) + "%"); + } + } + + class UsegeReminderSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (mViewHolder == null || mUsegeReminderValueBatteryDrawable == null || mViewHolder.tvUsegeReminderValue == null) return; + mViewHolder.tvUsegeReminderValue.setText(String.valueOf(progress) + "%"); + mUsegeReminderValueBatteryDrawable.setValue(progress); + mUsegeReminderValueBatteryDrawable.invalidateSelf(); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (mAppConfigUtils == null || mViewHolder == null || mViewHolder.tvUsegeReminderValue == null) return; + int nUsegeReminderValue = ((VerticalSeekBar) seekBar)._mnProgress; + mAppConfigUtils.setUsegeReminderValue(nUsegeReminderValue); + mViewHolder.tvUsegeReminderValue.setText(String.valueOf(nUsegeReminderValue) + "%"); + } + } + + + // ======================== 静态工具方法(Java 7 兼容,保持原有逻辑)======================== public static void relaodAppConfigs() { if (_mHandler != null) { _mHandler.sendMessage(_mHandler.obtainMessage(MSG_RELOAD_APPCONFIG)); @@ -549,88 +709,5 @@ public class MainActivity extends WinBoLLActivity { _mHandler.sendMessage(msg); } } - - /** - * 初始化实例(Application、工具类等) - */ - private void initInstance() { - _mMainActivity = this; - mApplication = (App) getApplication(); - // 初始化工具栏 - setSupportActionBar(mToolbar); - mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); - } - - /** - * 初始化主Fragment(添加并显示) - */ -// private void initFragment() { -// if (mMainViewFragment == null) { -// FragmentTransaction tx = getFragmentManager().beginTransaction(); -// mMainViewFragment = new MainViewFragment(); -// tx.add(R.id.activitymainFrameLayout1, mMainViewFragment, MainViewFragment.TAG); -// tx.commit(); -// } -// showFragment(mMainViewFragment); -// } - - class ChargeReminderSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener { - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - //LogUtils.d(TAG, "call onProgressChanged"); - int nChargeReminderValue = progress; - mtvChargeReminderValue.setText(Integer.toString(nChargeReminderValue) + "%"); - mChargeReminderValueBatteryDrawable.setValue(nChargeReminderValue); - mChargeReminderValueBatteryDrawable.invalidateSelf(); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - //LogUtils.d(TAG, "call onStartTrackingTouch"); - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - //LogUtils.d(TAG, "call onStopTrackingTouch"); - //取得当前进度条的刻度 - int nChargeReminderValue = ((VerticalSeekBar)seekBar)._mnProgress; - - mAppConfigUtils.setChargeReminderValue(nChargeReminderValue); - mtvChargeReminderValue.setText(Integer.toString(nChargeReminderValue) + "%"); - //ControlCenterService.updateChargeReminderValue(nChargeReminderValue); - } - } - - class UsegeReminderSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener { - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - //LogUtils.d(TAG, "call onProgressChanged"); - int nUsegeReminderValue = progress; - mtvUsegeReminderValue.setText(Integer.toString(nUsegeReminderValue) + "%"); - mUsegeReminderValueBatteryDrawable.setValue(nUsegeReminderValue); - mUsegeReminderValueBatteryDrawable.invalidateSelf(); - - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - //LogUtils.d(TAG, "call onStartTrackingTouch"); - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - //LogUtils.d(TAG, "call onStopTrackingTouch"); - //取得当前进度条的刻度 - int nUsegeReminderValue = ((VerticalSeekBar)seekBar)._mnProgress; - LogUtils.d(TAG, "nUsegeReminderValue is " + Integer.toString(nUsegeReminderValue)); - //LogUtils.d(TAG, "mPowerReminder is " + mApplication); - mAppConfigUtils.setUsegeReminderValue(nUsegeReminderValue); - //LogUtils.d(TAG, "opopopopopopopop"); - mtvUsegeReminderValue.setText(Integer.toString(nUsegeReminderValue) + "%"); - //ControlCenterService.updateUsegeReminderValue(nUsegeReminderValue); - } - } - } + diff --git a/powerbell/src/main/res/layout/activity_main.xml b/powerbell/src/main/res/layout/activity_main.xml index 56c1119..9556761 100644 --- a/powerbell/src/main/res/layout/activity_main.xml +++ b/powerbell/src/main/res/layout/activity_main.xml @@ -1,251 +1,259 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> - + + - + + - + + - + + - + + - + + - + - + - + - + - + + - + - + + - + - + - + - + - + + - + - + - + - + + - + - + - + - + + - + - + - + - + + - + - + - + - + - + - + - + + - + - + - + - + + + - + - - - + diff --git a/powerbell/src/main/res/layout/view_ads_banner.xml b/powerbell/src/main/res/layout/view_ads_banner.xml new file mode 100644 index 0000000..7822296 --- /dev/null +++ b/powerbell/src/main/res/layout/view_ads_banner.xml @@ -0,0 +1,7 @@ + + +