简介
通过Hook系统API实现启动时长、生命周期、UI绘制时间的检测,达到定量分析Activity性能问题的目标。
背景:
随着项目功能越来越多,存在部分页面启动时长过长的问题。需要一套定量统计启动过程中各个流程耗时多少的方案。
解决方案:
利用对系统ActivityThread中Instrumentation、Handler等系统API的hook,实现自动检测activity UI绘制时长、onCreate()、onStart()、onResume()等生命周期执行时长,Activity启动等时长。
下图是部分activity的启动流程,在Instrumentation的executeStartActivity() 打第一个点。
activity启动流程会先pause当前的activity,可以在IApplicationThread接受ams回调后的scheduleLaunchActivity后来再埋一个点。
Hook ActivityThread中mH handler,注入一个CallBack在handleMessage()时拦截一下,如果是100类型,启动LAUNCH_ACTIVITY的指令,打上一个点。对于大于26的api,由于改为transaction方式来执行,则在EXECUTE_TRANSACTION中监听。
Android系统通过ActivityThread中的Instrumentation来对Activity进行生命周期的管理,
自己实现一个instrumentation的代理类,复写executeStartActivity(), callActivityOnCreate(),callActivityOnStart(),callActivityOnResume()等,
然后注入到系统的ActivityThread中。
UI渲染时长统计:
Activity启动后,onCreate中只是对DecorView进行了初始化,真正的渲染在Activity的onResume()执行完后,WindowManagerImpl(addView())之前,可以在此处打起始点,并向Looper.myQueue()中添加IdleHandler。当onIdle执行的时候,View的绘制结束。
集成方式:
扩展:
Hook 系统API的机制还广泛用于插件化、热修复等技术中,缺点在于需要紧跟Android系统API的变化。
运行结果:
好处:
1.Android开发人员在做页面性能优化时,省去了各个页面繁琐的手动统计工作。
2.获得各阶段精细化的执行时间,方便定位问题。