美文网首页
Android耗电优化实践 (一)- 利用Hook方式监控排查耗

Android耗电优化实践 (一)- 利用Hook方式监控排查耗

作者: yueshao | 来源:发表于2019-02-21 18:18 被阅读0次

    Java Hook

    Hook 方案的好处在于使用者接入非常简单,不需要去修改自己的代码。下面我以几个比较常用的规则为例,看看如果使用 Java Hook 达到监控的目的。

    • WakeLock。WakeLock 用来阻止 CPU、屏幕甚至是键盘的休眠。类似 Alarm、JobService 也会申请 WakeLock 来完成后台 CPU 操作。WakeLock 的核心控制代码都在PowerManagerService中,实现的方法非常简单。
    // 代理 PowerManagerService
    ProxyHook().proxyHook(context.getSystemService(Context.POWER_SERVICE), "mService", this);
    
    @Override
    public void beforeInvoke(Method method, Object[] args) {
        // 申请 Wakelock
        if (method.getName().equals("acquireWakeLock")) {
            if (isAppBackground()) {
                // 应用后台逻辑,获取应用堆栈等等     
             } else {
                // 应用前台逻辑,获取应用堆栈等等
             }
        // 释放 Wakelock
        } else if (method.getName().equals("releaseWakeLock")) {
           // 释放的逻辑    
        }
    }
    
    
    // 代理 AlarmManagerService
    new ProxyHook().proxyHook(context.getSystemService
    (Context.ALARM_SERVICE), "mService", this);
    
    public void beforeInvoke(Method method, Object[] args) {
        // 设置 Alarm
        if (method.getName().equals("set")) {
            // 不同版本参数类型的适配,获取应用堆栈等等
        // 清除 Alarm
        } else if (method.getName().equals("remove")) {
            // 清除的逻辑
        }
    }
    
    
    • 其他。对于后台 CPU,我们可以使用卡顿监控相关的方法。对于后台网络,同样我们可以通过网络监控相关的方法。对于 GPS 监控,我们可以通过 Hook 代理LOCATION_SERVICE。对于 Sensor,我们通过 Hook SENSOR_SERVICE中的“mSensorListeners”,可以拿到部分信息。

    通过 Hook,我们可以在申请资源的时候将堆栈信息保存起来。当我们触发某个规则上报问题的时候,可以将收集到的堆栈信息、电池是否充电、CPU 信息、应用前后台时间等辅助信息也一起带上。

    开始编码

    下面开始lib_battery_hook的编写,这个框架花了两天时间完成,主要是里面代理Hook的实现,需要翻阅相关的源码并分析,最终实现了IAlarmManagerHook、IPowerManagerHook、ILocationManagerHook这三那个代理,分别实现对AlarmManager、PowerManager、LocationManager的监听。

    
    /**
     * @date on 2019/2/19
     * @author  lyg-hhy1
     * @email  yueshao6800@163.com
     * @describe
     */
    public class BatteryHookManager {
    
        /**
         * 初始化
         * @param context
         */
        public void initHook(Context context){
            //初始化日志
            BatteryLogUtil.init(context);
    
            //初始化Hook
            new IAlarmManagerHook(context).onInstall();
            new IPowerManagerHook(context).onInstall();
            new ILocationManagerHook(context).onInstall();
        }
    
    
    
    
        private BatteryHookManager(){}
        private static class BatteryHookManagerHolder{
            private static final BatteryHookManager INSTANCE= new BatteryHookManager();
        }
    
        public static BatteryHookManager getImp(){
            return BatteryHookManagerHolder.INSTANCE;
        }
    
    }
    

    在项目的application里面初始化BatteryHook,

    public class BatteryApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            BatteryHookManager.getImp().initHook(this);
    
        }
    }
    

    发现问题

    集成后,迫不及待跑了一下,果然看到了下面这些日志:

    LogCat里的日志

    这个好像是高德地图SDK的定位,每次项目启动app都会触发一次,

    在这里插入图片描述

    还发现一处比较诡异的,IMPushService长期持有设备唤醒锁,看了一下代码

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            try {
                if (wakeLock != null && !wakeLock.isHeld()) {
                    wakeLock.acquire();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            ……
        }
    
    
    
    
        @Override
        public void onDestroy() {
            if (wakeLock != null && wakeLock.isHeld()) {
                wakeLock.release();
            }
            wakeLock = null;
            ……
        }
    

    很奇怪,从IM的服务启动,到销毁,一直持有设备唤醒锁,这肯定非常的耗电。接下来我们采用的是Battery Historian2.0验证了一下,Historian2.0这是Google推出的一款Android系统电量分析工具,支持5.0(API 21)及以上系统手机的电量分析。

    修复并验证

    这是优化之前的好定分析:

    在这里插入图片描述
    在这里插入图片描述

    下面是去掉IMService中长期唤醒设备,这是优化之后的结果:

    在这里插入图片描述
    在这里插入图片描述

    统计结果如下:

    测试场景 测试时长 消耗电量
    去掉wakeLock之前 44m24s466ms 0.27%
    去掉之后 34m56s238ms 0.03%

    从测试结果可以看出,没有优化前耗电是优化后的9倍

    相关文章

      网友评论

          本文标题:Android耗电优化实践 (一)- 利用Hook方式监控排查耗

          本文链接:https://www.haomeiwen.com/subject/qhudyqtx.html