性能优化-卡顿
卡顿
线上监控方法:
方法1:Coreographer帧率检测,postFrameCallback ,保存两次 doFrame 时间进行相减然后除以刷新频率,这样算出来的结果就是两次 doFrame 的掉帧数
方法2:Looper设置print ,匹配消息分发前后字符串,计算之间的耗时
方法3:开启个线程循环通过主线程Handle,post一个延迟x秒的消息去修改一个值,睡眠x秒后在去看下这个值是否修改了
线下监控方法
1、利用Systetrace工具
1
systrace.py -a com.duowan.gamevoice sched freq idle am wm gfx view binder_driver hal dalvik camera input res
只要带上sched 就可以看到自定义的beginSection
2、profile traceView 打印出详细调用堆栈
profile 手动记录时间段
指定监控方法,通过代码自定义开始和结束,有的文件分析不了可能是后面参数设置太小了,文件写的不全
1
Debug.startMethodTracing("/sdcard/gameVoiceMethodTrace_app",1024*1024*20);
3、系统自带工具 StrictMode
避免主线成io耗时操作
使用StrictMode 检测主线程是否有io,网络等耗时操作会打印到logcat中
// 启用 StrictMode
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.detectAll() // 检测所有问题
.penaltyLog() // 输出问题信息到日志
.build();
StrictMode.setThreadPolicy(policy);
4、第三方工具:BlockCananry
ANR
什么是ANR?
当应用程序在一段时间内未能响应用户输入或系统事件时,Android系统会主动生成ANR错误
ANR一般有以下几种类型,具体数值KeyDispatchTimeout:按键事件在5s的时间内没有处理完成。
BroadcastTimeout:广播接收器在前台10s,后台60s的时间内没有响应完成。
ServiceTimeout:服务在前台20s,后台200s的时间内没有处理完成。
主线程阻塞,广播接收器处理耗时,服务未响应,服务执行耗时任务,主线程死锁等都可能会导致ANR
但并不一定主线程耗时任务就会出现anr如下面这种情况,如果后续没有事件需要处理是不会产生anr的
ANR如何监控
方法一:6.0 以下手机监听 用FileObserver 监听/data/anr/trace.txt 文件,变化了之后调用AMS 获取进程状态,getProcessesInErrorState方法二:6.0 以上获取 通过jni 调用 sigaction 注册监听 SIGQUIT信号,然后在去AMS查询状态。signal 3信号就是ANR
方法三:直接定期轮训查AMS的状态
方法四:AnrWatchDog,原理:开启个线程循环通过主线程Handle,post一个延迟x秒的消息去修改一个值,睡眠x秒后在去看下这个值是否修改了,没有判断为ANR,还可以查询小AMS状态二次校验下。非侵入式,不需要hook
ANR trace文件获取
线下收集trace文件1
2#适合6.0 以下
adb pull /data/anr/trace.txt
线上收集trace,
通过sigaction 设置个signalHandler
Xhook hook write 函数拿到trace文件,这个文件包含很全面的anr信息
1 | #适合6.0以上,没有权限获取了 |
崩溃异常辅助日志搜集
/system/bin/logcat 手机自己的日志工具,也可以用adb locat
1 | #查看崩溃日志缓冲区(默认) |
通过popen获取得到输入命令文件,然后fgets读出结果
1 | char* types[] = {"crash", "system", "events", "main"}; |
功耗优化:
SurfaceView 替换 TextureView
CPU 数据上看,SurfaceView 要比 TextureView 优化 8%-13%
功耗数据上看,SurfaceView 要比 TextureView 平均功耗低 20mA 左右。
硬件绘制,代替软件绘制
视频硬编解替换软编解
减少过度绘制
减少刷新区域
减少刷新频率
CPU负载优化
长链接心跳
GSP
耗