Android 8.1 Battery系列(七) BatteryStatsHelper类和耗电量统计

本文深入剖析Android 8.1中的BatteryStatsHelper类,阐述其在电量统计中的作用,从初始化、计算电池使用时间到耗电量统计,包括BatterySipper类的构造和功能,帮助理解Android系统的电量管理机制。
摘要由CSDN通过智能技术生成

概述

BatteryStatsHelper类用于负责计算各个应用和服务的电量使用情况,利用BatteryStatsService中统计的时长和电源配置文件中的配置值,通过计算得到耗电量信息供Application层使用。在Settings通过refreshStats()方法从BatteryStatsHelper中获取电池的数据。下面就BatteryStatsHelper从实例化到计算系统用电情况进行分析。

代码路径:
/frameworks/base/core/java/com/android/internal/os/BatteryStatsHelper.java

1.BatteryStatsHelper的初始化方法

要使用BatteryStatsHelper,必须获取其实例,并调用create()方法。因此这里看看其构造方法和create()方法,代码如下:


public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast, boolean wifiOnly) {
   
    mContext = context;
    //是否需要注册BATTERY_CHANGED广播
    mCollectBatteryBroadcast = collectBatteryBroadcast;
    //平板等无移动网络,故该值为true
    mWifiOnly = wifiOnly;
    mPackageManager = context.getPackageManager();
    final Resources resources = context.getResources();
    //表示将数组中的包名作为系统进程对待
    mSystemPackageArray = resources.getStringArray(
            com.android.internal.R.array.config_batteryPackageTypeSystem);
    //表示将数组中的包名作为系统服务对待
    mServicepackageArray = resources.getStringArray(
            com.android.internal.R.array.config_batteryPackageTypeService);
}

create()方法:


public void create(BatteryStats stats) {
   
    mPowerProfile = new PowerProfile(mContext);
    mStats = stats;
}

public void create(Bundle icicle) {
   
    if (icicle != null) {
   
        mStats = sStatsXfer;
        mBatteryBroadcast = sBatteryBroadcastXfer;
    }
    mBatteryInfo = IBatteryStats.Stub.asInterface(
            ServiceManager.getService(BatteryStats.SERVICE_NAME));
    mPowerProfile = new PowerProfile(mContext);
}

构造方法比较简单。create()方法有两个重载,它们有个共同点:获取了PowerProfile对象,这个类在Battery系列三中已经分析过了,是电源配置文件。除此之外,还获得了BatteryStats对象。

1.1.refreshStats()方法

这个方法作为Application层刷新电池使用数据的接口,向上提供数据。电池统计的主要逻辑都是在这个方法中实现的,源代码如下:

public void refreshStats(int statsType, SparseArray<UserHandle> asUsers, long rawRealtimeUs,
        long rawUptimeUs) {
   
    // Initialize mStats if necessary.
    //获取BatteryStatsImpl对象
    getStats();

    mMaxPower = 0;//最大耗电量
    mMaxRealPower = 0;//最大真实耗电量
    mComputedPower = 0;//通过耗电计算器计算的耗电量总和
    mTotalPower = 0;//总的耗电量

    //存储了BatterySipper的列表,各类耗电量都存储在BatterySipper中,BatterySipper又放在了mUsageList中
    mUsageList.clear();
    //在统计软件耗电过程中使用到wifi的应用对应的BatterySipper列表
    mWifiSippers.clear();
    //在统计软件耗电过程中使用到BT的应用对应的BatterySipper列表
    mBluetoothSippers.clear();
    //设备上有多个用户时,存储了其他用户的耗电信息的SparseArray数据,键为userId,值为对应的List<BatterySipper>
    mUserSippers.clear();
    //存储有数据接受和发送的BatterySipper对象的列表
    mMobilemsppList.clear();

    if (mStats == null) {
   
        return;
    }
    //初始化八个耗电量计算器,此处不做详细分析
    if (mCpuPowerCalculator == null) {
   
        mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile);
    }
    mCpuPowerCalculator.reset();

    if (mMemoryPowerCalculator == null) {
   
        mMemoryPowerCalculator = new MemoryPowerCalculator(mPowerProfile);
    }
    mMemoryPowerCalculator.reset();

    if (mWakelockPowerCalculator == null) {
   
        mWakelockPowerCalculator = new WakelockPowerCalculator(mPowerProfile);
    }
    mWakelockPowerCalculator.reset();

    if (mMobileRadioPowerCalculator == null) {
   
        mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile, mStats);
    }
    mMobileRadioPowerCalculator.reset(mStats);

    // checkHasWifiPowerReporting can change if we get energy data at a later point, so
    // always check this field.
    final boolean hasWifiPowerReporting = checkHasWifiPowerReporting(mStats, mPowerProfile);
    if (mWifiPowerCalculator == null || hasWifiPowerReporting != mHasWifiPowerReporting) {
   
        mWifiPowerCalculator = hasWifiPowerReporting ?
                new WifiPowerCalculator(mPowerProfile) :
                new WifiPowerEstimator(mPowerProfile);
        mHasWifiPowerReporting = hasWifiPowerReporting;
    }
    mWifiPowerCalculator.reset();

    final boolean hasBluetoothPowerReporting = checkHasBluetoothPowerReporting(mStats,
            mPowerProfile);
    if (mBluetoothPowerCalculator == null ||
            hasBluetoothPowerReporting != mHasBluetoothPowerReporting) {
   
        mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile);
        mHasBluetoothPowerReporting = hasBluetoothPowerReporting;
    }
    mBluetoothPowerCalculator.reset();

    if (mSensorPowerCalculator == null) {
   
        mSensorPowerCalculator = new SensorPowerCalculator(mPowerProfile,
                (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE));
    }
    mSensorPowerCalculator.reset();

    if (mCameraPowerCalculator == null) {
   
        mCameraPowerCalculator = new CameraPowerCalculator(mPowerProfile);
    }
    mCameraPowerCalculator.reset();

    if (mFlashlightPowerCalculator == null) {
   
        mFlashlightPowerCalculator = new FlashlightPowerCalculator(mPowerProfile);
    }
    mFlashlightPowerCalculator.reset();

    //统计类型,有三种:上次充满电后、上次充电后、当前
    mStatsType = statsType;
    //当前系统运行时间
    mRawUptimeUs = rawUptimeUs;
    //当前系统运行时间,包括休眠时间
    mRawRealtimeUs = rawRealtimeUs;
    //电池放电运行时间
    mBatteryUptimeUs = mStats.getBatteryUptime(rawUptimeUs);
    //电池放电运行时间,包括休眠时间
    mBatteryRealtimeUs = mStats.getBatteryRealtime(rawRealtimeUs);
    //对应类型的电池放电运行时间,如上次充满电后的电池运行时间
    mTypeBatteryUptimeUs = mStats.computeBatteryUptime(rawUptimeUs, mStatsType);
    //对应类型的电池放电运行时间,包括休眠时间
    mTypeBatteryRealtimeUs = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType);
    //电池预计使用时长
    mBatteryTimeRemainingUs = mStats.computeBatteryTimeRemaining(rawRealtimeUs);
    //电池预计多久充满时长
    mChargeTimeRemainingUs = mStats.computeChargeTimeRemaining(rawRealtimeUs);

    //最低放电量近似值 = (最低放电等级近似值 * PowerProfile中配置电池容量) / 100,是BatteryStatsService中统计的最低放电量近似值
    mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
            * mPowerProfile.getBatteryCapacity()) / 100;
    //最高放电量近似值 = (最高放电等级近似值 * PowerProfile中配置电池容量) / 100,是BatteryStatsService中统计的最高放电量近似值
    mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
            * mPowerProfile.getBatteryCapacity()) / 100;

    //统计软件的耗电量,统计之后,会将每种类型、每个uid的耗电值存储在对应的BatterySipper中
    processAppUsage(asUsers);

    // Before aggregating apps in to users, collect all apps to sort by their ms per packet.
    //计算每个BatterySipper(每个应用)的每毫接收和发送的数据包mobilemspp
    for (int i = 0; i < mUsageList.size(); i++) {
   
        BatterySipper bs = mUsageList.get(i);
        bs.computeMobilemspp();
        //如果对应应用的mobilemspp!=0,则将该BatterySipper加入到mMobilemsppList列表中
        if (bs.mobilemspp != 
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值