part 8 App电量优化

Part 8 App电量优化

一 电量优化介绍及方案选择

1、正确认识

电量重视度不够:开发中一直连着手机
电量消耗线上难以量化

2、方案介绍

设置界面-耗电排行

直观,但是没有详细数据,对解决问题没有太多帮助
找特定场景专项测试(如在详情页中进行一段时间的操作)

注册电量相关的广播ACTION_BATTERY_CHANGED

获取电池电量、充电状态、电池状态等信息
价值不大:针对手机整体的耗电量。而非特定的App

        //示例代码
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = registerReceiver(null, filter);
        LogUtils.i("battery " + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));

Battery Historain

Google推出的一款Android系统电量分析工具
支持5.0(API21)及以上系统的电量分析
功能强大,推荐使用
可视化的展示指标:耗电比例、执行时间、次数
适合线下使用

3、测试相关

耗电场景测试:复杂运算、视频播放
传感器相关:使用时长、耗电量、发热
后台静默测试

二 Battery Historain实战分析

1、安装

https://github.com/google/battery-historian
安装Docker(http://www.runoob.com/docker/docker-tutorial.html 教程)
docker – run -p :9999 gcr.io/android-battery-historian/stable:3.0 --port 9999

2、导出电量信息

adb shell dumpsys batterystats --reset 电量重置
adb shell dumpsys batterystats --enable full-wake-history 开始记录电量信息
adb shell bugreport bugreport.zip 导出电量信息

3、上传问题

http://localhost:9999
上传bugreport文件即可
备用:https://bathist.ef.lc/

在这里插入图片描述

三 电量辅助监控

1、运行时能耗

获取各个模块的能耗(如屏幕、wifi,bluetooth等)
adb pull /system/framework/framework-res.apk
反编译,xml ————> power_profile

在这里插入图片描述

2、运行时获取使用时长

Aop辅助统计:次数、时间
以WakeLock为例子
https://www.cnblogs.com/leipDao/p/8241468.html (安卓电量优化之WakeLock锁机制全面解析)
https://www.jianshu.com/p/67ccdac38271 (Android 功耗分析之wakelock)

public class WakeLockUtils {

    private static PowerManager.WakeLock sWakeLock;

    public static void acquire(Context context){
        if(sWakeLock == null){
            sWakeLock = createWakeLock(context);
        }
        if(sWakeLock != null && !sWakeLock.isHeld()){
            sWakeLock.acquire();
            sWakeLock.acquire(1000);
        }
    }

    public static void release(){
        // 一些逻辑
        try{

        }catch (Exception e){

        }finally {
            // 为了演示正确的使用方式
            if(sWakeLock != null && sWakeLock.isHeld()){
                sWakeLock.release();
                sWakeLock = null;
            }
        }
    }

    @SuppressLint("InvalidWakeLockTag")
    private static PowerManager.WakeLock createWakeLock(Context context){
        PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
        if(pm != null){
            return pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"");
        }
        return null;
    }

}



 // 此处模拟的是WakeLock使用的兜底策略
    WakeLockUtils.acquire(holder.imageView.getContext());
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            WakeLockUtils.release();
        }
    },200);
    
    //通过Hooker监控
public class ActivityHooker {

    public static ActivityRecord sActivityRecord;

    static {
        sActivityRecord = new ActivityRecord();
    }

    public static String trace;

    public static long sStartTime = 0;

    @Insert(value = "acquire")
    @TargetClass(value = "com.optimize.performance.wakelock.WakeLockUtils",scope = Scope.SELF)
    public static void acquire(Context context){
        trace = Log.getStackTraceString(new Throwable());
        sStartTime = System.currentTimeMillis();
        Origin.callVoid();
        //兜底策略
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                WakeLockUtils.release();
            }
        },1000);
    }

    @Insert(value = "release")
    @TargetClass(value = "com.optimize.performance.wakelock.WakeLockUtils",scope = Scope.SELF)
    public static void release(){
        LogUtils.i("PowerManager "+(System.currentTimeMillis() - sStartTime)+"/n"+trace);
        Origin.callVoid();
    }
}    

3、线程运行时长

超过阀值预警(运行时间过长可以停止)

   public static long runTime = 0;

    @Insert(value = "run")
    @TargetClass(value = "java.lang.Runnable",scope = Scope.ALL)
    public void run(){
        runTime = System.currentTimeMillis();
        Origin.callVoid();
        LogUtils.i("runTime "+(System.currentTimeMillis() - runTime));
    }

四 电量优化套路总结

1、CPU时间片

获取运行过程线程CPU的消耗,定位CPU占用率异常位置
减少后台应用的主动运行

2、网络相关

发起网络请求时机及次数
数据压缩,减少时间
禁止使用轮询功能进行业务操作

3、定位相关

根据场景谨慎选择定位模式(精度,频率)
考虑网络定位代替GPS
使用后及时关闭,减少更新

4、界面相关

离开界面后停止相关活动
耗电操作判断前后台

5、wakelock相关

注意成对出现:acquire与release
使用带参数的acquire
finally确保一定会被释放
常亮场景使用keeoScreenOn即可

6、JobScheduler

在符合某些条件时创建执行在后台的任务
把不紧急的任务放到更合适的时机批量处理
https://www.jianshu.com/p/9fb882cae239 (Android Jobscheduler使用)

//创建任务
public class JobSchedulerService extends JobService {

    @Override
    public boolean onStartJob(JobParameters params) {
        // 此处执行在主线程
        // 模拟一些处理:批量网络请求,APM日志上报
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}

//manifest注册
<service android:name=".net.JobSchedulerService"
    android:permission="android.permission.BIND_JOB_SERVICE"/>

    /**
     * 演示JobScheduler的使用
     */
    private void startJobScheduler() {
        //5.0之后才能使用
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
            JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
            builder.setRequiresCharging(true)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
            jobScheduler.schedule(builder.build());
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值