@@ -51,66 +51,62 @@ import cc.winboll.studio.powerbell.views.BatteryDrawable;
import cc.winboll.studio.powerbell.views.VerticalSeekBar ;
/**
* 主活动类( Java 7 兼容 | 首屏加速改造:视图缓存+懒加载 )
* 核心优化点(解决首次启动慢) :
* 1. ViewHolder 缓存控件,避免首次多次 findViewById
* 2. ViewStub 延迟加载非首屏关键视图(广告、次要布局)
* 3. 核心视图预加载+ 资源异步加载
* 4. 非关键任务(服务检查、数据初始化)异步化
* 5. 减少首次启动时的同步 inflate 耗时
* 修复点:解决首次加载图片失败问题(背景图+电量图标)
* 主活动类( Java 7 兼容 | 首屏加速+窗体缓存 )
* 核心优化点:
* 1. ViewHolder 缓存控件 + ViewStub 延迟加载(原有)
* 2. savedInstanceState 窗体缓存(新增):缓存视图状态/数据,快速重建窗体
* 3. 资源异步加载 + 非关键任务异步化(原有)
*/
public class MainActivity extends WinBoLLActivity {
// ======================== 静态常量(首屏排列,统一管理 ) ========================
// ======================== 静态常量(新增: savedInstanceState 缓存键 ) ========================
public static final String TAG = " MainActivity " ;
private static final int REQUEST_WRITE_STORAGE_PERMISSION = 1001 ;
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)
public static final int MSG_LOAD_BACKGROUND = 2 ;
private static final int DELAY_LOAD_NON_CRITICAL = 500 ;
// ======================== 成员属性( 按「静态→非静态」「核心→辅助」排序, ViewHolder 优先)========================
// 全局静态引用(控制生命周期)
// 缓存键(统一管理,避免键名重复)
private static final String KEY_VIEW_STATE = " key_view_state " ; // 视图状态缓存键
private static final String KEY_CHARGE_REMINDER = " key_charge_reminder " ; // 充电提醒值
private static final String KEY_USEGE_REMINDER = " key_usege_reminder " ; // 耗电提醒值
private static final String KEY_CURRENT_VALUE = " key_current_value " ; // 当前电量值
private static final String KEY_IS_SERVICE_ENABLE = " key_is_service_enable " ; // 服务开关状态
private static final String KEY_IS_CHARGE_ENABLE = " key_is_charge_enable " ; // 充电提醒开关
private static final String KEY_IS_USEGE_ENABLE = " key_is_usege_enable " ; // 耗电提醒开关
private static final String KEY_BACKGROUND_BEAN = " key_background_bean " ; // 背景配置Bean
// ======================== 成员属性(保持原有,新增缓存标识)========================
public static MainActivity _mMainActivity ;
static MainViewFragment _mMainViewFragment ;
static Handler _mHandler ;
// 核心工具类(提前初始化,避免首次同步耗时)
private App mApplication ;
private AppConfigUtils mAppConfigUtils ;
private BackgroundSourceUtils mBgSourceUtils ;
// 顶部导航与广告( 非首屏核心, 用ViewStub延迟加载)
private Toolbar mToolbar ;
private ViewStub mAdsViewStub ; // 广告视图占位符(首次不加载)
private ViewStub mAdsViewStub ;
private ADsBannerView mADsBannerView ;
// 视图缓存核心: ViewHolder( 一次性绑定所有控件, 避免多次findViewById)
private ViewHolder mViewHolder ;
// 其他辅助属性
private Menu mMenu ;
private Fragment mCurrentShowFragment ;
private MainViewFragment mMainViewFragment ;
private Drawable mDrawableFrame ;
// 电量图示( 首次初始化耗时, 放入ViewHolder缓存)
private BatteryDrawable mCurrentValueBatteryDrawable ;
private BatteryDrawable mChargeReminderValueBatteryDrawable ;
private BatteryDrawable mUsegeReminderValueBatteryDrawable ;
// 新增: 缓存标识( 判断是否从savedInstanceState恢复, 避免重复初始化)
private boolean isRestoredFromCache = false ;
// ======================== 视图缓存容器( ViewHolder 模式, Java 7 兼容)========================
/**
* ViewHolder 静态内部类:一次性绑定所有控件,缓存实例
* 避免首次启动时多次调用 findViewById( 遍历视图树耗时) , 仅在首次 inflate 后绑定一次
*/
// ======================== 视图缓存容器( ViewHolder 不变)========================
private static class ViewHolder {
// 首屏核心视图(必须优先加载)
BackgroundView backgroundView ; // 背景视图(首屏关键,图片加载核心)
RelativeLayout mainLayout ; // 主布局(设置背景色,首屏关键)
// 电量控制核心控件(首屏必须显示)
BackgroundView backgroundView ;
RelativeLayout mainLayout ;
LinearLayout llLeftSeekBar , llRightSeekBar ;
CheckBox cbIsEnableChargeReminder , cbIsEnableUsegeReminder ;
Switch swIsEnableService ;
@@ -120,7 +116,7 @@ public class MainActivity extends WinBoLLActivity {
}
// ======================== 重写父类抽象方法(优先排列,明确实现 ) ========================
// ======================== 重写生命周期( 核心: savedInstanceState 缓存/恢复 ) ========================
@Override
public Activity getActivity ( ) {
return this ;
@@ -133,72 +129,118 @@ public class MainActivity extends WinBoLLActivity {
@Override
protected void onCreate ( Bundle savedInstanceState ) {
LogUtils . d ( TAG , " onCreate(...) - 首屏加速改造( Java 7 兼容)- 修复图片加载 " ) ;
LogUtils . d ( TAG , " onCreate(...) - 窗体缓存优化: savedInstanceState = " + ( savedInstanceState ! = null ) ) ;
super . onCreate ( savedInstanceState ) ;
// 关键优化2: 提前初始化全局Handler( 避免首次使用时创建耗时, Java 7 简化写法)
initGlobalHandler ( ) ;
// 1. 快速加载布局( 仅加载首屏核心视图, 非核心用ViewStub占位 )
setContentView ( R . layout . activity_main ) ;
// 第一步: 优先从savedInstanceState恢复窗体( 核心优化 )
if ( savedInstanceState ! = null ) {
restoreFromCache ( savedInstanceState ) ; // 从缓存恢复视图/数据
isRestoredFromCache = true ; // 标记为缓存恢复,跳过重复初始化
}
// 2. 初始化核心工具类( 异步初始化, 避免阻塞主线程, Java 7 线程创建方式 )
initCoreUtilsAsync ( ) ;
// 第二步:无缓存时,正常初始化(保持原有逻辑,新增判断 )
if ( ! isRestoredFromCache ) {
setContentView ( R . layout . activity_main ) ; // 加载布局(仅首次/无缓存时执行)
initCoreUtilsAsync ( ) ; // 异步初始化工具类
initViewHolder ( ) ; // 绑定控件(仅首次/无缓存时执行)
initCriticalView ( ) ; // 初始化核心视图
loadNonCriticalViewDelayed ( ) ; // 延迟加载非核心视图
}
// 3. 初始化ViewHolder( 一次性绑定所有控件, 缓存实例, 核心加速点 )
initViewHolder ( ) ;
// 4. 初始化首屏核心视图(必须同步加载,保证首屏显示)
initCriticalView ( ) ;
// 5. 延迟加载非首屏核心视图(广告、次要控件,首屏渲染后再加载)
loadNonCriticalViewDelayed ( ) ;
// 6. 权限申请(轻量操作,同步执行)
// 第三步:权限申请(无论是否缓存,都需确保权限有效 )
PermissionUtils . getInstance ( ) . checkAndRequestStoragePermission ( this ) ;
}
/**
* 重写 onSaveInstanceState: 保存视图状态/数据到 savedInstanceState( 关键)
* 当Activity销毁前( 如旋转屏幕、后台回收) , 自动调用此方法缓存数据
*/
@Override
protected void onSaveInstanceState ( Bundle outState ) {
super . onSaveInstanceState ( outState ) ;
LogUtils . d ( TAG , " onSaveInstanceState - 缓存窗体状态/数据 " ) ;
// 1. 缓存控件数据(避免重建后重复读取配置)
if ( mViewHolder ! = null & & mAppConfigUtils ! = null ) {
outState . putInt ( KEY_CHARGE_REMINDER , mAppConfigUtils . getChargeReminderValue ( ) ) ;
outState . putInt ( KEY_USEGE_REMINDER , mAppConfigUtils . getUsegeReminderValue ( ) ) ;
outState . putInt ( KEY_CURRENT_VALUE , mAppConfigUtils . getCurrentValue ( ) ) ;
outState . putBoolean ( KEY_IS_SERVICE_ENABLE , mAppConfigUtils . getIsEnableService ( ) ) ;
outState . putBoolean ( KEY_IS_CHARGE_ENABLE , mViewHolder . cbIsEnableChargeReminder . isChecked ( ) ) ;
outState . putBoolean ( KEY_IS_USEGE_ENABLE , mViewHolder . cbIsEnableUsegeReminder . isChecked ( ) ) ;
}
// 2. 缓存背景配置(避免重建后重复加载背景图)
if ( mBgSourceUtils ! = null ) {
BackgroundBean backgroundBean = mBgSourceUtils . getCurrentBackgroundBean ( ) ;
if ( backgroundBean ! = null ) {
outState . putSerializable ( KEY_BACKGROUND_BEAN , backgroundBean ) ; // 需BackgroundBean实现Serializable
}
}
// 3. 缓存视图状态( 可选: 如SeekBar进度、控件可见性等)
if ( mViewHolder ! = null ) {
outState . putInt ( KEY_VIEW_STATE + " _charge_seek " , mViewHolder . chargeReminderSeekBar . getProgress ( ) ) ;
outState . putInt ( KEY_VIEW_STATE + " _usege_seek " , mViewHolder . usegeReminderSeekBar . getProgress ( ) ) ;
}
}
/**
* 重写 onRestoreInstanceState: 从 savedInstanceState 恢复数据( 可选, onCreate中已处理)
* 确保在onStart后、onResume前恢复, 避免视图状态覆盖
*/
@Override
protected void onRestoreInstanceState ( Bundle savedInstanceState ) {
super . onRestoreInstanceState ( savedInstanceState ) ;
if ( savedInstanceState ! = null & & ! isRestoredFromCache ) {
restoreFromCache ( savedInstanceState ) ;
isRestoredFromCache = true ;
}
}
@Override
protected void onDestroy ( ) {
super . onDestroy ( ) ;
// 释放资源,避免内存泄漏
// 释放资源(保持原有)
if ( mADsBannerView ! = null ) {
mADsBannerView . releaseAdResources ( ) ;
}
// 置空静态引用
_mMainActivity = null ;
_mMainViewFragment = null ;
// 移除Handler回调( Java 7 兼容)
if ( _mHandler ! = null ) {
_mHandler . removeCallbacksAndMessages ( null ) ;
}
// 重置缓存标识
isRestoredFromCache = false ;
}
@Override
protected void onResume ( ) {
super . onResume ( ) ;
// 修复1: 移除此处背景刷新( 避免工具类未初始化完成时调用, 导致图片加载失败 )
// reloadBackground();
// setBackgroundColor();
// 改为: 发送消息让Handler控制加载时机( 确保工具类已初始化)
if ( _mHandler ! = null ) {
_mHandler . sendEmptyMessage ( MSG_LOAD_BACKGROUND ) ;
// 缓存恢复后,无需重复发送加载消息(仅首次/无缓存时执行 )
if ( ! isRestoredFromCache ) {
if ( _mHandler ! = null ) {
_mHandler . sendEmptyMessage ( MSG_LOAD_BACKGROUND ) ;
}
} else {
// 缓存恢复后,快速刷新视图(避免状态不一致)
refreshViewFromCache ( ) ;
}
// 非核心: 恢复广告(仅在首次延迟加载后执行 )
// 恢复广告(保持原有 )
if ( mADsBannerView ! = null ) {
mADsBannerView . resumeADs ( MainActivity . this ) ;
}
}
// 其他生命周期方法( onCreateOptionsMenu、onOptionsItemSelected等保持原有不变)
@Override
public boolean onCreateOptionsMenu ( Menu menu ) {
mMenu = menu ;
// 主题菜单(轻量,同步加载)
AESThemeUtil . inflateMenu ( this , menu ) ;
// 调试菜单( 仅Debug模式, 轻量)
if ( App . isDebugging ( ) ) {
DevelopUtils . inflateMenu ( this , menu ) ;
}
// 应用核心菜单(轻量,同步加载)
getMenuInflater ( ) . inflate ( R . menu . toolbar_main , mMenu ) ;
return true ;
}
@@ -206,17 +248,14 @@ 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 ) ) ;
@@ -248,7 +287,6 @@ 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 ) ;
@@ -275,35 +313,134 @@ public class MainActivity extends WinBoLLActivity {
}
// ======================== 核心业务逻辑方法( 按功能优先级排序, Java 7 兼容 ) ========================
// ======================== 新增:窗体缓存核心方法(恢复+刷新 ) ========================
/**
* 刷新背景(仅执行必要操作,避免首次耗时 )
* 从 savedInstanceState 恢复视图和数据(核心 )
* 避免重复加载布局、绑定控件、读取配置,加快窗体重建速度
*/
private void restoreFromCache ( Bundle savedInstanceState ) {
LogUtils . d ( TAG , " restoreFromCache - 从缓存恢复窗体 " ) ;
// 1. 恢复工具类(无需重新初始化,直接获取实例)
mApplication = ( App ) getApplication ( ) ;
mAppConfigUtils = App . getAppConfigUtils ( getActivity ( ) ) ;
mBgSourceUtils = BackgroundSourceUtils . getInstance ( getActivity ( ) ) ;
// 2. 恢复ViewHolder( 仅绑定控件, 不重新inflate布局)
if ( mViewHolder = = null ) {
mViewHolder = new ViewHolder ( ) ;
initViewHolder ( ) ; // 复用原有绑定逻辑,避免重复代码
}
// 3. 恢复背景配置( 直接设置缓存的BackgroundBean, 避免重复读取)
BackgroundBean cachedBean = ( BackgroundBean ) savedInstanceState . getSerializable ( KEY_BACKGROUND_BEAN ) ;
if ( cachedBean ! = null & & mViewHolder . backgroundView ! = null ) {
mViewHolder . backgroundView . loadBackgroundBean ( cachedBean ) ;
//mBgSourceUtils.setCurrentBackgroundBean(cachedBean); // 同步更新工具类缓存
}
// 4. 恢复控件数据( 从缓存读取, 避免重复调用AppConfigUtils)
int chargeReminder = savedInstanceState . getInt ( KEY_CHARGE_REMINDER , 80 ) ; // 默认值80
int usegeReminder = savedInstanceState . getInt ( KEY_USEGE_REMINDER , 20 ) ; // 默认值20
int currentValue = savedInstanceState . getInt ( KEY_CURRENT_VALUE , 50 ) ; // 默认值50
boolean isServiceEnable = savedInstanceState . getBoolean ( KEY_IS_SERVICE_ENABLE , false ) ;
boolean isChargeEnable = savedInstanceState . getBoolean ( KEY_IS_CHARGE_ENABLE , false ) ;
boolean isUsegeEnable = savedInstanceState . getBoolean ( KEY_IS_USEGE_ENABLE , false ) ;
// 5. 恢复电量图标(复用缓存实例,避免重新创建)
initBatteryDrawables ( ) ;
mCurrentValueBatteryDrawable . setValue ( currentValue ) ;
mChargeReminderValueBatteryDrawable . setValue ( chargeReminder ) ;
mUsegeReminderValueBatteryDrawable . setValue ( usegeReminder ) ;
// 6. 恢复控件状态(直接设置,避免重复绑定数据)
if ( mViewHolder ! = null ) {
mViewHolder . cbIsEnableChargeReminder . setChecked ( isChargeEnable ) ;
mViewHolder . cbIsEnableUsegeReminder . setChecked ( isUsegeEnable ) ;
mViewHolder . swIsEnableService . setChecked ( isServiceEnable ) ;
mViewHolder . chargeReminderSeekBar . setProgress ( savedInstanceState . getInt ( KEY_VIEW_STATE + " _charge_seek " , chargeReminder ) ) ;
mViewHolder . usegeReminderSeekBar . setProgress ( savedInstanceState . getInt ( KEY_VIEW_STATE + " _usege_seek " , usegeReminder ) ) ;
mViewHolder . tvChargeReminderValue . setText ( String . valueOf ( chargeReminder ) + " % " ) ;
mViewHolder . tvUsegeReminderValue . setText ( String . valueOf ( usegeReminder ) + " % " ) ;
mViewHolder . tvCurrentValue . setText ( String . valueOf ( currentValue ) + " % " ) ;
}
// 7. 恢复非核心视图(广告)
loadAdsView ( ) ;
}
/**
* 缓存恢复后,快速刷新视图(确保状态一致)
*/
private void refreshViewFromCache ( ) {
if ( mViewHolder = = null ) return ;
// 快速设置背景色( 从缓存Bean获取)
if ( mBgSourceUtils ! = null & & mViewHolder . mainLayout ! = null ) {
BackgroundBean cachedBean = mBgSourceUtils . getCurrentBackgroundBean ( ) ;
if ( cachedBean ! = null ) {
mViewHolder . mainLayout . setBackgroundColor ( cachedBean . getPixelColor ( ) ) ;
}
}
// 快速设置电量图标(避免图标不显示)
if ( mViewHolder . ivCurrentBattery ! = null ) {
mViewHolder . ivCurrentBattery . setImageDrawable ( mCurrentValueBatteryDrawable ) ;
}
if ( mViewHolder . ivChargeReminderBattery ! = null ) {
mViewHolder . ivChargeReminderBattery . setImageDrawable ( mChargeReminderValueBatteryDrawable ) ;
}
if ( mViewHolder . ivUsegeReminderBattery ! = null ) {
mViewHolder . ivUsegeReminderBattery . setImageDrawable ( mUsegeReminderValueBatteryDrawable ) ;
}
// 重新绑定监听(确保交互正常,避免监听失效)
setViewListener ( ) ;
}
/**
* 初始化电量图标(复用逻辑,避免重复代码)
*/
private void initBatteryDrawables ( ) {
if ( mCurrentValueBatteryDrawable = = null ) {
mCurrentValueBatteryDrawable = new BatteryDrawable ( getActivity ( ) . getColor ( R . color . colorCurrent ) ) ;
}
if ( mChargeReminderValueBatteryDrawable = = null ) {
mChargeReminderValueBatteryDrawable = new BatteryDrawable ( getActivity ( ) . getColor ( R . color . colorCharge ) ) ;
}
if ( mUsegeReminderValueBatteryDrawable = = null ) {
mUsegeReminderValueBatteryDrawable = new BatteryDrawable ( getActivity ( ) . getColor ( R . color . colorUsege ) ) ;
}
}
// ======================== 原有核心方法(微调:新增缓存判断,避免重复执行)========================
/**
* 刷新背景(新增缓存判断,缓存恢复后无需重复执行)
*/
public void reloadBackground ( ) {
// 修复3: 增加多重判空( 避免工具类/视图未初始化导致空指针,图片加载失败)
if ( isRestoredFromCache ) return ; // 缓存恢复后,跳过重复加载
if ( mViewHolder = = null | | mBgSourceUtils = = null | | mViewHolder . backgroundView = = null ) {
LogUtils . e ( TAG , " reloadBackground: 背景加载失败(控件/工具类未初始化) " ) ;
return ;
}
// 仅加载背景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 ) ;
}
}
/**
* 设置主页面背景颜色(首屏关键,同步执行但轻量化 )
* 设置主页面背景颜色(新增缓存判断 )
*/
void setBackgroundColor ( ) {
if ( isRestoredFromCache ) return ;
if ( isFinishing ( ) | | isDestroyed ( ) | | mViewHolder = = null | | mBgSourceUtils = = null | | mViewHolder . mainLayout = = null ) {
return ;
}
// 轻量化操作:仅获取颜色值并设置,避免额外耗时
BackgroundBean bean = mBgSourceUtils . getCurrentBackgroundBean ( ) ;
if ( bean ! = null ) {
int nPixelColor = bean . getPixelColor ( ) ;
@@ -312,85 +449,36 @@ public class MainActivity extends WinBoLLActivity {
}
/**
* 通过Uri获取文件本地真实路径( 按需加载, 不影响首屏 )
*/
private String getRealPathFromURI ( Uri contentUri ) {
String [ ] proj = { MediaStore . MediaColumns . DATA } ;
Cursor cursor = getContentResolver ( ) . query ( contentUri , proj , null , null , null ) ;
if ( cursor ! = null & & cursor . moveToNext ( ) ) {
int nColumnIndex = cursor . getColumnIndex ( MediaStore . MediaColumns . DATA ) ;
if ( nColumnIndex > - 1 ) {
String path = cursor . getString ( nColumnIndex ) ;
cursor . close ( ) ;
return path ;
}
cursor . close ( ) ;
}
return null ;
}
/**
* 生成默认APP信息( 按需加载, 不影响首屏)
*/
APPInfo genDefaultAPPInfo ( ) {
String szBranchName = " powerbell " ;
APPInfo appInfo = new APPInfo ( ) ;
appInfo . setAppName ( getString ( R . string . app_name ) ) ;
appInfo . setAppIcon ( R . drawable . ic_launcher ) ;
appInfo . setAppDescription ( getString ( R . string . app_description ) ) ;
appInfo . setAppGitName ( " WinBoLL " ) ;
appInfo . setAppGitOwner ( " Studio " ) ;
appInfo . setAppGitAPPBranch ( szBranchName ) ;
appInfo . setAppGitAPPSubProjectFolder ( szBranchName ) ;
appInfo . setAppHomePage ( " https://www.winboll.cc/apks/index.php?project=PowerBell " ) ;
appInfo . setAppAPKName ( " PowerBell " ) ;
appInfo . setAppAPKFolderName ( " PowerBell " ) ;
return appInfo ;
}
/**
* 设置视图数据(首屏核心,同步执行但轻量化)
* 设置视图数据(新增缓存判断,缓存恢复后无需重复执行 )
*/
void setViewData ( ) {
if ( isRestoredFromCache ) return ;
if ( mViewHolder = = null | | mAppConfigUtils = = null ) return ;
int nChargeReminderValue = mAppConfigUtils . getChargeReminderValue ( ) ;
int nUsegeReminderValue = mAppConfigUtils . getUsegeReminderValue ( ) ;
int nCurrentValue = mAppConfigUtils . getCurrentValue ( ) ;
// 轻量化设置:仅绑定必要数据,避免复杂计算
if ( mViewHolder . llLeftSeekBar ! = null & & mViewHolder . llRightSeekBar ! = null & & mDrawableFrame ! = null ) {
mViewHolder . llLeftSeekBar . setBackground ( mDrawableFrame ) ;
mViewHolder . llRightSeekBar . setBackground ( mDrawableFrame ) ;
}
// 电量图示初始化(首次耗时,缓存实例)
// 修复4: 电量图标判空容错( 避免控件未绑定导致图片加载失败)
initBatteryDrawables ( ) ; // 复用初始化逻辑
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 ) + " % " ) ;
@@ -427,13 +515,13 @@ public class MainActivity extends WinBoLLActivity {
}
}
// 其他原有方法( setViewListener、setCurrentValueBattery、initCoreUtilsAsync等保持不变)
/**
* 设置视图监听(首屏核心, 同步执行但轻量化, Java 7 移除Lambda, 用匿名内部类 )
* 设置视图监听(保持原有 )
*/
void setViewListener ( ) {
if ( mViewHolder = = null | | mAppConfigUtils = = null ) return ;
// 充电提醒SeekBar监听
if ( mViewHolder . chargeReminderSeekBar ! = null ) {
mViewHolder . chargeReminderSeekBar . setOnSeekBarChangeListener ( new ChargeReminderSeekBarChangeListener ( ) ) ;
}
@@ -446,7 +534,6 @@ public class MainActivity extends WinBoLLActivity {
} ) ;
}
// 耗电提醒SeekBar监听
if ( mViewHolder . usegeReminderSeekBar ! = null ) {
mViewHolder . usegeReminderSeekBar . setOnSeekBarChangeListener ( new UsegeReminderSeekBarChangeListener ( ) ) ;
}
@@ -459,7 +546,6 @@ public class MainActivity extends WinBoLLActivity {
} ) ;
}
// 服务总开关监听( Java 7 用CompoundButton.OnClickListener匿名内部类)
if ( mViewHolder . swIsEnableService ! = null ) {
mViewHolder . swIsEnableService . setOnClickListener ( new CompoundButton . OnClickListener ( ) {
@Override
@@ -471,7 +557,7 @@ public class MainActivity extends WinBoLLActivity {
}
/**
* 更新当前电量显示(轻量化,避免耗时 )
* 更新当前电量显示(保持原有 )
*/
void setCurrentValueBattery ( int value ) {
if ( mViewHolder = = null | | mCurrentValueBatteryDrawable = = null | | mViewHolder . tvCurrentValue = = null ) return ;
@@ -480,16 +566,11 @@ public class MainActivity extends WinBoLLActivity {
mCurrentValueBatteryDrawable . invalidateSelf ( ) ;
}
// ======================== 首屏加速核心辅助方法( Java 7 兼容)========================
/**
* 初始化ViewHolder( 核心优化1: 一次性绑定所有控件, 避免首次多次findViewById )
* 仅在onCreate中执行一次, 后续直接复用缓存的控件实例
* 初始化ViewHolder( 保持原有 )
*/
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不匹配) " ) ;
@@ -510,15 +591,12 @@ public class MainActivity extends WinBoLLActivity {
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 ) ;
}
/**
* 初始化核心工具类(异步化, 核心优化2: 避免首次同步初始化耗时, Java 7 线程创建 )
* 工具类初始化( 如AppConfigUtils、BackgroundSourceUtils) 可能涉及文件读取, 异步执行不阻塞首屏
* 初始化核心工具类(保持原有 )
*/
private void initCoreUtilsAsync ( ) {
new Thread ( new Runnable ( ) {
@@ -527,20 +605,15 @@ public class MainActivity extends WinBoLLActivity {
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 ) ;
}
@@ -551,59 +624,48 @@ public class MainActivity extends WinBoLLActivity {
}
/**
* 初始化首屏核心视图(同步执行,保证首屏显示 )
* 仅加载必须显示的视图,非核心视图延迟加载
* 初始化首屏核心视图(保持原有 )
*/
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, 不阻塞首屏
View adsView = mAdsViewStub . 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 ( ) {
@@ -619,8 +681,7 @@ public class MainActivity extends WinBoLLActivity {
}
/**
* 初始化全局Handler( 提前初始化, 避免首次使用时创建耗时, Java 7 简化写法 )
* 修复7: 新增MSG_LOAD_BACKGROUND消息, 统一控制背景加载时机( 确保工具类+控件都已初始化)
* 初始化全局Handler( 保持原有 )
*/
private void initGlobalHandler ( ) {
if ( _mHandler = = null ) {
@@ -638,10 +699,10 @@ public class MainActivity extends WinBoLLActivity {
_mMainActivity . setCurrentValueBattery ( msg . arg1 ) ;
}
break ;
case MSG_LOAD_BACKGROUND : // 新增:背景图片加载消息
case MSG_LOAD_BACKGROUND :
if ( _mMainActivity ! = null ) {
_mMainActivity . reloadBackground ( ) ; // 加载背景图
_mMainActivity . setBackgroundColor ( ) ; // 设置背景色
_mMainActivity . reloadBackground ( ) ;
_mMainActivity . setBackgroundColor ( ) ;
}
break ;
}
@@ -651,7 +712,7 @@ public class MainActivity extends WinBoLLActivity {
}
}
// ======================== 内部监听类( Java 7 兼容,保持原有逻辑)========================
// 内部监听类(保持原有)
class ChargeReminderSeekBarChangeListener implements SeekBar . OnSeekBarChangeListener {
@Override
public void onProgressChanged ( SeekBar seekBar , int progress , boolean fromUser ) {
@@ -694,8 +755,7 @@ public class MainActivity extends WinBoLLActivity {
}
}
// ======================== 静态工具方法( Java 7 兼容,保持原有逻辑)========================
// 静态工具方法(保持原有)
public static void relaodAppConfigs ( ) {
if ( _mHandler ! = null ) {
_mHandler . sendMessage ( _mHandler . obtainMessage ( MSG_RELOAD_APPCONFIG ) ) ;
@@ -709,5 +769,36 @@ public class MainActivity extends WinBoLLActivity {
_mHandler . sendMessage ( msg ) ;
}
}
private String getRealPathFromURI ( Uri contentUri ) {
String [ ] proj = { MediaStore . MediaColumns . DATA } ;
Cursor cursor = getContentResolver ( ) . query ( contentUri , proj , null , null , null ) ;
if ( cursor ! = null & & cursor . moveToNext ( ) ) {
int nColumnIndex = cursor . getColumnIndex ( MediaStore . MediaColumns . DATA ) ;
if ( nColumnIndex > - 1 ) {
String path = cursor . getString ( nColumnIndex ) ;
cursor . close ( ) ;
return path ;
}
cursor . close ( ) ;
}
return null ;
}
APPInfo genDefaultAPPInfo ( ) {
String szBranchName = " powerbell " ;
APPInfo appInfo = new APPInfo ( ) ;
appInfo . setAppName ( getString ( R . string . app_name ) ) ;
appInfo . setAppIcon ( R . drawable . ic_launcher ) ;
appInfo . setAppDescription ( getString ( R . string . app_description ) ) ;
appInfo . setAppGitName ( " WinBoLL " ) ;
appInfo . setAppGitOwner ( " Studio " ) ;
appInfo . setAppGitAPPBranch ( szBranchName ) ;
appInfo . setAppGitAPPSubProjectFolder ( szBranchName ) ;
appInfo . setAppHomePage ( " https://www.winboll.cc/apks/index.php?project=PowerBell " ) ;
appInfo . setAppAPKName ( " PowerBell " ) ;
appInfo . setAppAPKFolderName ( " PowerBell " ) ;
return appInfo ;
}
}