[20191207][Android10]高德地图导航功耗场景优化

2024-02-09 19:38

本文主要是介绍[20191207][Android10]高德地图导航功耗场景优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘要

在这里插入图片描述

1. 测试现象

1.1 EPRODUCING PROCEDURES:

1.进入高德 Map(data) wifi),起点为自己所在位置,搜索一个位置进行导航;
2.等待30秒后开始记录电流,持续5分钟;
3.按Power键,灭屏待机;
4.手机灭屏15秒后开始记录电流,持续3分钟;

1.2 Test numberSummary
设备高德地图导航
测试机461.82 mA
对比机369.13 mA

2.分析

2.1 拔屏以扣除LCD影响
设备高德地图导航
测试机+450nit带屏幕导航405.18 mA
对比机+450nit带屏幕导航380.11
测试机+拔屏174.45 mA
对比机+拔屏131.76 mA

从上述看扣掉 LCD 同样有功耗差异,即LCD 关系不大

注意:导航场景:一般是带导航语音,即需要考虑Audio的影响

2.2 设计实验找出问题差异

以下是我自己设计的实验方法

1).对比机与测试机的GPS搜星实验
  1. GPS puls 搜星查看,我apk放到附件中
  2. 只开启GPS+飞行模式
  3. 尽量2台机器相同环境下同时测试
    4.放置5分钟后,apk主界面截图
GPS plus+工具搜星情况
对比机无GPS信号增强器观察卫星数量和信号强度
对比机有GPS信号增强器观察卫星数量和信号强度
测试机无GPS信号增强器观察卫星数量和信号强度
测试机有GPS信号增强器观察卫星数量和信号强度

实验发现:基本无差异,故 GPS 单体应该是没问题

2).导航电流测试
  1. 最暗亮度测试,避免扣掉屏幕带来的影响
  2. 静音+插入耳机,去除导航语音带来的影响
  3. 尽量2台机器相同环境下同时测试
测试项目测试机器(mA)对比机(mA)
case 1 静态HOME界面固定墙纸_飞行模式65.2168.19
case 2网络定位条件,高德导航测试:只保持WiFi连接,飞行模式87.6388.95
case 3 GPS定位条件,高德导航测试:开启GPS+插卡+WiFi 连接147.63120.71
case 4 GPS定位条件,高德导航测试:GPS增强器+开启GPS+插卡+WiFi 连接169.64153.48
  • case 1 目的: 对比相同亮度下是否存在差异
  • case 2 目的: 查看是否网络定位有问题
  • case 3 目的:查看是否GPS定位存问题
  • case 3 目的: 查杀是否与GPS信号强度有关,因为室内是GPS信号比较弱

上述:

  • case 1 说明测试机和对比机亮屏下相同亮度的测试电流是基本一致,即基础的系统功耗是相同的
  • case 2 说明网络定位是OK的,说明相同APK在不同机器测试,运行是后台也基本保持一致,且说明如果GPS不开启则是导航是好的;
  • case 3、case 4 说明GPS开启,会带来导航功耗影响
3).GPS单体功耗

这块数据没有,故需要让硬件提供:

测试步骤:

Wi-Fi Off, GPS ON, BT OFF, NFC OFF, Fly mode ON.
灭屏,等待1min,记录平均电流,即是打开GPS时的电流。
在上述的条件时,记录下可以稳定复现的最小电流值,即是 GPS floor current.
Average current when GPS navigation working:Step1:通过下拉菜单,打开飞行模式,打开位置服务;
Step2:进入工程模式 adb shell am start -n com.mediatek.ygps/com.mediatek.ygps.YgpsActivity;
Step3:进入Location->YGPS->Enable in BG.(need restart),重启后再次进入该界面;
Step4:关闭屏幕,待电流稳定,测试3分钟,记录电流A1;
Step5:通过下拉菜单,关闭位置服务;
Step6:进入工程模式,进入Location->YGPS,再回到YGPS界面;
Step7:关闭屏幕,待电流稳定,测试3分钟,记录电流A2;
GPS ON=A1-A2

由于不知道 ygps 源码,通过测试步骤基本猜到,主要是测试GPS开启电流和工作电流,相当于高德地图的定位场景,非导航场景

测试数据:

设备平均电流
测试机34mA
对比机34mA

从上面数据看,GPS的工作电流是基本一致的,即GPS单体是OK的

这就奇怪了,GPS单体是好的,为什么导航一开GPS就存问题呢?还需要再排除干扰。例如以下干扰:

  1. WiFi 环境因素
  2. 4G 插卡因素
  3. 应用启动后会进行页面、地图数据、配置文件下载
  4. 测试过程中,如果网络发生变化,热点不稳定
4).离线导航
  1. Wi-Fi Off, GPS ON, BT OFF, NFC OFF, Fly mode ON,排除WiFi带来的干扰
  2. 最小亮度
  3. 使用 what_temp apk抓CPU数据
  4. 静音插耳机
  5. 使用高德离线地图导航
设备测试机对比机
高德地图定位界面55.13mA50.13mA
高德地图导航界面83.00mA60.49mA

上述查看:

  1. 现象复现,即排除了Wi-Fi Off, GPS ON, BT OFF, NFC OFF, Fly mode影响,即wifi、4G都没问题
  2. 定位场景差异不大,导航场景差异比较大。
  3. 需要查看高德地图定位细节
2.3 高德地图的dump信息

dumpsys location|grep -B 2 “com.autonavi.minimap”

Tokyo_Lite:/ $ dumpsys location|grep -B 2 "com.autonavi.minimap"Battery Saver Location Mode: NO_CHANGELocation Listeners:Reciever[35eed63 listener UpdateRecord[passive com.autonavi.minimap(10167 foreground) Request[POWER_NONE passive fastest=0] null], isNeedBgGpsRestrict false monitoring location: true]Reciever[fe54b41 listener UpdateRecord[passive android(1000 foreground) Request[POWER_NONE passive fastest=+30m0s0ms] null], isNeedBgGpsRestrict false monitoring location: true]Reciever[a523146 listener UpdateRecord[passive com.autonavi.minimap(10167 foreground) Request[POWER_NONE passive fastest=+1s0ms] null], isNeedBgGpsRestrict false monitoring location: true]Reciever[4698940 listener UpdateRecord[passive android(1000 foreground) Request[POWER_NONE passive fastest=0] null], isNeedBgGpsRestrict false monitoring location: false]Reciever[3e939ea listener monitoring location: false]Reciever[a629ca9 listener UpdateRecord[gps com.autonavi.minimap(10167 foreground) Request[ACCURACY_FINE gps requested=+1s0ms fastest=+1s0ms] null], isNeedBgGpsRestrict false monitoring location: true]Active Records by Provider:gps:UpdateRecord[gps com.autonavi.minimap(10167 foreground) Request[ACCURACY_FINE gps requested=+1s0ms fastest=+1s0ms] null], isNeedBgGpsRestrict false
--UpdateRecord[passive android(1000 foreground) Request[POWER_NONE passive fastest=0] null], isNeedBgGpsRestrict falseUpdateRecord[passive android(1000 foreground) Request[POWER_NONE passive fastest=+30m0s0ms] null], isNeedBgGpsRestrict falseUpdateRecord[passive com.autonavi.minimap(10167 foreground) Request[POWER_NONE passive fastest=0] null], isNeedBgGpsRestrict falseUpdateRecord[passive com.autonavi.minimap(10167 foreground) Request[POWER_NONE passive fastest=+1s0ms] null], isNeedBgGpsRestrict false
--Active GnssNavigationMessage Listeners:Active GnssStatus Listeners:5600 10167 com.autonavi.minimap: false5600 10167 com.autonavi.minimap: false5600 10167 com.autonavi.minimap: false5766 10167 com.autonavi.minimap: falseHistorical Records by Provider:android: passive: Min interval 0 seconds: Max interval 1800 seconds: Duration requested 99 total, 99 foreground, out of the last 99 minutes: Currently activecom.autonavi.minimap: passive: Min interval 0 seconds: Max interval 1 seconds: Duration requested 2 total, 2 foreground, out of the last 98 minutes: Currently activecom.autonavi.minimap: gps: Interval 1 seconds: Duration requested 2 total, 2 foreground, out of the last 98 minutes: Currently active

查看高德地图的dump信息,我们基本知道高德地图申请了哪些定位:

  1. GPS 定位,定位间隔1秒一个
    Reciever[a629ca9 listener UpdateRecord[gps com.autonavi.minimap(10167 foreground) Request[ACCURACY_FINE gps requested=+1s0ms fastest=+1s0ms] null], isNeedBgGpsRestrict false monitoring location: true]
  2. passive 定位
    Reciever[a523146 listener UpdateRecord[passive com.autonavi.minimap(10167 foreground) Request[POWER_NONE passive fastest=+1s0ms] null], isNeedBgGpsRestrict false monitoring location: true]
  3. 监听了 GnssStatus 数据
    Active GnssStatus Listeners:
    5600 10167 com.autonavi.minimap: false
    5600 10167 com.autonavi.minimap: false
    5600 10167 com.autonavi.minimap: false
    5766 10167 com.autonavi.minimap: false
2.4 分析高德地图定位和导航调用的函数

我们在dump locaiton已经知道高德地图会申请使用GPS,并且定位间隔为1秒,故不需要在

1) LocationManager 埋点
public class LocationManager {public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener, @Nullable Handler handler) {boolean result;// huazhi.suif("true".equals(SystemProperties.get("persist.sys.tct.addNmeaListener.debug", "false"))) {Log.e(TAG, "skip addNmeaListener");return false;}// huazhi.su@RequiresPermission(ACCESS_FINE_LOCATION)public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback, @Nullable Handler handler) {boolean result;synchronized (mGnssStatusListeners) {// huazhi.suif("true".equals(SystemProperties.get("persist.sys.tct.registerGnssStatusCallback.debug", "false"))) {if("com.autonavi.minimap".equals(mContext.getPackageName())) {Log.e(TAG, "skip registerGnssStatusCallback  packageName:" + mContext.getPackageName());}return false;}// huazhi.su
2) 查看导航场景高德地图使用的sdk情况
场景API接口
定位场景requestLocationUpdates、registerGnssStatusCallback
导航场景requestLocationUpdates、registerGnssStatusCallback、addNmeaListener

即导航场景比定位场景多了 addNmeaListener

12-06 14:10:44.728  3716  3716 W System.err:    at android.location.LocationManager.addNmeaListener(LocationManager.java:2046)
12-06 14:10:44.736  3716  4034 W System.err:    at android.location.LocationManager.registerGnssStatusCallback(LocationManager.java:1944)locationManager.registerGnssStatusCallback(new GnssStatus.Callback() {@Overridepublic void onSatelliteStatusChanged(GnssStatus status) {super.onSatelliteStatusChanged(status);Log.d(TAG, "onSatelliteStatusChanged");}});locationManager.addNmeaListener(new OnNmeaMessageListener() {@Overridepublic void onNmeaMessage(String message, long timestamp) {Log.d(TAG, "onNmeaMessage message :" + message + ", timestamp :" + timestamp);sendRequestWithHttpClient();}});locationManager.requestLocationUpdates(GPS_PROVIDER, 1000, 0, mMyLocationListener);
  1. 之前的测试GPS单体的功耗基本是 requestLocationUpdates 这个接口的功能,故 基本问题不大
  2. 且导航和定位场景中,导航场景存在和定位场景不同,故我们可以单独屏蔽掉 registerGnssStatusCallback、addNmeaListener

3. 问题根源研究

3.1 禁止监听 GnssStatus 和 Nmea
测试项平均电流备注
离线导航133异常电流波形
离线导航+禁止监听 GnssStatus120异常电流波形
离线导航+禁止监听 Nmea110异常电流波形
离线导航+禁止监听 Nmea + GnssStatus100正常电流波形

首先我们看下异常电流:特征是一秒钟一个波峰,且单个异常波形平均电流就有166mA,基本功耗不被拉大才怪
异常电流

上述说明:监听 Nmea + GnssStatus 会带来功耗,但是肯定要给第三方应用正常使用这个数据

3.1 拦截 GnssStatus 和 Nmea

拦截位置

package com.android.server.location;public class GnssLocationProvider ...{@NativeEntryPoint // libgnss.so上报private void reportNmea(long timestamp) {// 新增拦截...// 对应上层的:public void onNmeaMessage(String message, long timestamp) 方法...}@NativeEntryPoint // libgnss.so上报private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,// 新增拦截...// 对应上层的:public void onSatelliteStatusChanged(GnssStatus status) { 方法...}}
测试项平均电流备注
离线导航133异常电流波形
离线导航+拦截 GnssStatus 数据上报123异常电流波形
离线导航+拦截 Nmea 数据上报110异常电流波形
离线导航+拦截 Nmea + GnssStatus 数据上报100正常电流波形

拦截测试也说明 Nmea + GnssStatus 有影响,难道高德地图会收到数据做一些耗电操作,还是对比机有优化呢?
由于高德地图、对比机没有源码,所以我们无法知道,从源码一个函数一个函数地分析。看是否源代码有问题,即了解GPS的Nmea + GnssStatus上报给上层的源码

4. 源码分析并新增日志

4.1 源码数据通路新增日志

例如 Nmea 数据如何上报给上层apk,在这个数据传递的通路新增日志,每个函数调用的地方都加

1.数据源头-------------------------------------------------
package com.android.server.location;@NativeEntryPointprivate void reportNmea(long timestamp) {if (!mItarSpeedLimitExceeded) {int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);String nmea = new String(mNmeaBuffer, 0 /* offset */, length);mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);}}2.-------------------------------------------------
public abstract class GnssStatusListenerHelper extends RemoteListenerHelper<IGnssStatusListener> {public void onNmeaReceived(final long timestamp, final String nmea) {// 遍历 addNmeaListener 监听数量,例如高德地图使用了2个,一个定位注册的,一个导航场景注册的foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {// 检查是否与定位权限if (hasPermission(mContext, callerIdentity)) {logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName, "NMEA");return;}// 消息传递到上层listener.onNmeaReceived(timestamp, nmea);});}
}
3.-------------------------------------------------
public class LocationManager {@Overridepublic void onNmeaReceived(long timestamp, String nmea) {...mGnssHandler.obtainMessage(NMEA_RECEIVED).sendToTarget();...}for (Nmea nmea : mNmeaBuffer) {// 数据给上层mGnssNmeaListener.onNmeaMessage(nmea.mNmea, nmea.mTimestamp);}
4.2 现象发现
1)日志大量打印,这里1秒钟70组数据从底层上报出来,都需要经过上述的函数,简直是太频繁
01-01 00:04:54.516  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GNGGA,160454.011,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*5F
01-01 00:04:54.516  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GNGGA,160454.011,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*5F
01-01 00:04:54.518  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GNGGA,160454.011,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*5F
01-01 00:04:54.519  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
01-01 00:04:54.520  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
01-01 00:04:54.522  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
01-01 00:04:54.522  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
01-01 00:04:54.522  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GLGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2C
01-01 00:04:54.524  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GLGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2C
01-01 00:04:54.524  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GLGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2C
01-01 00:04:54.526  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GLGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2C
01-01 00:04:54.526  3740  4447 E LocationManager: skip onNmeaReceived: nmea$BDGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.527  3328  4051 E LocationManager: skip onNmeaReceived: nmea$BDGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.527  3328  4051 E LocationManager: skip onNmeaReceived: nmea$BDGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.527  3328  4561 E LocationManager: skip onNmeaReceived: nmea$BDGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.528  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GAGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.529  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GAGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.529  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GAGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.529  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GAGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*21
01-01 00:04:54.531  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GPGSV,1,1,0*49
01-01 00:04:54.531  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GPGSV,1,1,0*49
01-01 00:04:54.531  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GPGSV,1,1,0*49
01-01 00:04:54.533  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GLGSV,1,1,0*55
01-01 00:04:54.533  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GLGSV,1,1,0*55
01-01 00:04:54.534  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GPGSV,1,1,0*49
01-01 00:04:54.534  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GLGSV,1,1,0*55
01-01 00:04:54.535  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GLGSV,1,1,0*55
01-01 00:04:54.535  3740  4447 E LocationManager: skip onNmeaReceived: nmea$BDGSV,1,1,0*58
01-01 00:04:54.536  3328  4051 E LocationManager: skip onNmeaReceived: nmea$BDGSV,1,1,0*58
01-01 00:04:54.536  3328  4561 E LocationManager: skip onNmeaReceived: nmea$BDGSV,1,1,0*58
01-01 00:04:54.536  3328  4561 E LocationManager: skip onNmeaReceived: nmea$BDGSV,1,1,0*58
01-01 00:04:54.537  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GAGSV,1,1,0*58
01-01 00:04:54.537  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GAGSV,1,1,0*58
01-01 00:04:54.538  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GAGSV,1,1,0*58
01-01 00:04:54.538  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GAGSV,1,1,0*58
01-01 00:04:54.539  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GNRMC,160454.011,V,8960.0000,N,00000.0000,E,0.000,0.00,311218,,,N*55
01-01 00:04:54.539  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GNRMC,160454.011,V,8960.0000,N,00000.0000,E,0.000,0.00,311218,,,N*55
01-01 00:04:54.539  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GNRMC,160454.011,V,8960.0000,N,00000.0000,E,0.000,0.00,311218,,,N*55
01-01 00:04:54.540  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C
01-01 00:04:54.541  3328  4561 E LocationManager: skip onNmeaReceived: nmea$GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C
01-01 00:04:54.542  3328  3345 E LocationManager: skip onNmeaReceived: nmea$GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C
01-01 00:04:54.542  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GNRMC,160454.011,V,8960.0000,N,00000.0000,E,0.000,0.00,311218,,,N*55
01-01 00:04:54.542  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C
01-01 00:04:54.542  3740  4447 E LocationManager: skip onNmeaReceived: nmea$PMTKTSX1,5012,326233.306,43.336,38.845,59000000,32.622746,32.623331,0.000000,-0.225000,0.000000,32.623*7C
01-01 00:04:54.543  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKTSX1,5012,326233.306,43.336,38.845,59000000,32.622746,32.623331,0.000000,-0.225000,0.000000,32.623*7C
01-01 00:04:54.544  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKTSX1,5012,326233.306,43.336,38.845,59000000,32.622746,32.623331,0.000000,-0.225000,0.000000,32.623*7C
01-01 00:04:54.544  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKTSX1,5012,326233.306,43.336,38.845,59000000,32.622746,32.623331,0.000000,-0.225000,0.000000,32.623*7C
01-01 00:04:54.544  3740  4447 E LocationManager: skip onNmeaReceived: nmea$PMTKGEPH,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*04
01-01 00:04:54.545  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKGEPH,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*04
01-01 00:04:54.545  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKGEPH,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*04
01-01 00:04:54.546  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKGEPH,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*04
01-01 00:04:54.546  3740  4447 E LocationManager: skip onNmeaReceived: nmea$PMTKGALM,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*19
01-01 00:04:54.547  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKGALM,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*19
01-01 00:04:54.547  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKGALM,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*19
01-01 00:04:54.548  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKGALM,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*19
01-01 00:04:54.548  3740  4447 E LocationManager: skip onNmeaReceived: nmea$GNACCURACY,3162.1,180.0,3.5,500.0*29
01-01 00:04:54.548  3328  4051 E LocationManager: skip onNmeaReceived: nmea$GNACCURACY,3162.1,180.0,3.5,500.0*29
01-01 00:04:54.549  3328  3345 E LocationManager: skip onNmeaReceived: nmea$GNACCURACY,3162.1,180.0,3.5,500.0*29
01-01 00:04:54.549  3328  3345 E LocationManager: skip onNmeaReceived: nmea$GNACCURACY,3162.1,180.0,3.5,500.0*29
01-01 00:04:54.550  3740  4447 E LocationManager: skip onNmeaReceived: nmea$PMTKAGC,160454.011,6174,6241,7189,7273,0,0,0*68
01-01 00:04:54.550  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKAGC,160454.011,6174,6241,7189,7273,0,0,0*68
01-01 00:04:54.551  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKAGC,160454.011,6174,6241,7189,7273,0,0,0*68
01-01 00:04:54.551  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKAGC,160454.011,6174,6241,7189,7273,0,0,0*68
01-01 00:04:54.553  3740  4447 E LocationManager: skip onNmeaReceived: nmea$PMTKAG2,160454.011,6*1C
01-01 00:04:54.553  3328  4051 E LocationManager: skip onNmeaReceived: nmea$PMTKAG2,160454.011,6*1C
01-01 00:04:54.553  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKAG2,160454.011,6*1C
01-01 00:04:54.554  3328  3345 E LocationManager: skip onNmeaReceived: nmea$PMTKAG2,160454.011,6*1C
2)异常发现

发现只要去掉 hasPermission 的调用,功耗就能掉下来,没想到是这个函数搞得鬼

    public void onNmeaReceived(final long timestamp, final String nmea) {foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {// huazhi.su add startif("true".equals(SystemProperties.get("persist.sys.Helper.hasPermission", "false"))) {// 实测1秒中被调用了70次,去除后平均电流减少20mA// 这个判断作用:若用户定位的时候突然关闭GPS权限,则也要相应停止数据上报到上层// 出发点是好:但是1秒钟判断了70次就不厚道了,且不同应用注册的数量不同,故这里的次数也不一样if (!hasPermission(mContext, callerIdentity)) {logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName, "NMEA");return;}}// huazhi.su add endlistener.onNmeaReceived(timestamp, nmea);});protected boolean hasPermission(Context context, CallerIdentity callerIdentity) {if (LocationPermissionUtil.doesCallerReportToAppOps(context, callerIdentity)) {// The caller is identified as a location provider that will report location// access to AppOps. Skip noteOp but do checkOp to check for location permission.return mAppOps.checkOpNoThrow(AppOpsManager.OP_FINE_LOCATION, callerIdentity.mUid,callerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;}return mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, callerIdentity.mUid,callerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;}

上述中 reportSvStatus 也使用到了 hasPermission 的判断,但是实测回调的次数没有 reportNmea多,故功耗电流小一些

    public void onSvStatusChanged (...hasPermission(mContext, callerIdentity)...}

5. 问题发现与解决

5.1. 功耗问题原因

去掉了 hasPermission 就好,说明系统也经不起频繁执行某个函数的方法

5.2. 分析

源码也存在问题,为什么这么频繁调用的地方,每次都是执行一个函数,干嘛不把这个变量的状态保持下来。读状态比去执行函数的效率高多了。
估计 Google 写这个函数的时候,没考虑的这里实际会被频繁调用到

5.3. 解决方案
  1. 监听权限变化事件,当权限改变的时候,更新下对应uid的权限,并保存起来
    context.getPackageManager().addOnPermissionsChangeListener(mOnPermissionsChangedListener);private OnPermissionsChangedListener mOnPermissionsChangedListener = new OnPermissionsChangedListener() {public void onPermissionsChanged(int uid) {updatePermissionsChanged(uid);}};
  1. 若当前保存了uid的权限状态,则读状态,而不是每次执行函数获取,提高效率
    private boolean isHasPermission(Context context, CallerIdentity callerIdentity) {if(mPermissionsList.containsKey(callerIdentity.mUid)) {return mPermissionsList.get(callerIdentity.mUid);} else {boolean isHasPermission = hasPermission(mContext, callerIdentity);mPermissionsList.put(callerIdentity.mUid, isHasPermission);return isHasPermission;}}

5.4 高德地图导航场景电流优化了 30mA

优化后电流由 133mA 下降到100mA, 1秒钟一个的异常波形也消失了。
由于这里数据是我自己测的

在这里插入图片描述

这篇关于[20191207][Android10]高德地图导航功耗场景优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695110

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

构建高性能WEB之HTTP首部优化

0x00 前言 在讨论浏览器优化之前,首先我们先分析下从客户端发起一个HTTP请求到用户接收到响应之间,都发生了什么?知己知彼,才能百战不殆。这也是作为一个WEB开发者,为什么一定要深入学习TCP/IP等网络知识。 0x01 到底发生什么了? 当用户发起一个HTTP请求时,首先客户端将与服务端之间建立TCP连接,成功建立连接后,服务端将对请求进行处理,并对客户端做出响应,响应内容一般包括响应