activity启动流程
- Launcher进程中ActivityManagerProxy:点击app图标,Launcher进程通过Binder IPC向system_server发起startActivity请求
- system_server进程中ActivityManagerService:接收到请求后,向zygote进程发送创建进程的请求
- zygote进程:fork出新的子进程,即App进程
- App进程中AcitivtyManagerProxy:通过Binder IPC 向system_server--ActivityManagerService发起attachApplication的请求
- system_server进程中ActivityManagerService:接收到请求后,一系列准备后通过Binder IPC 向App进程发起scheduleLaunchActivity请求
- App进程中binder线程ApplicationThread:收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息
- App进程中ActivityThread:主线程在收到Message后,通过反射创建目标Activity,并回到Activity.onCreate等生命周期方法
- App正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume 方法,ui渲染后可看到主界面
启动状态
- 冷启动:从头开始启动,冷启动后才创建进程;设备关闭或者杀进程后启动。
- 热启动:将Activity带到前台,只要应用的所有Activity还在内存中,就不用再重复执行初始化
布局加载、绘制 - 温启动:许多潜在状态可视为温启动
用户退出应用后重新启动应用;进程可能还未被销毁,但应用需要重头开始创建oncreate;
应用内存释放又重新启动,传递到oncreate里面的saveinstancestate对于完成此任务有益
启动耗时
命令:adb shell am start -S -W 包名/.activity名
重要值:totaltime,总时间
CPU Profile(默认版本8.0以上,用对于的执行按钮运行)
- 大概看下:Call Chart:时间轴越长标识耗时越长;分了颜色标记系统和用户及第三方的;新版貌似没了
- 大概看下:Flame Chart:和Call Chart排序相反
- 常用:Top Down:记录中的方法调用栈查看,精确每一步耗时;从main出发一步步进入对象
- 大概看下:Boom Up: 和Top Down顺序相反,从对象出发看引用
- 老版本用:Application里面加上Debug.StartMethodTracing("相对路径文件名");需要结束的地方加上Debug.StopMethodTracing()
StrictModel
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
黑白屏
Theme中设置背景图的方式解决。
- BackgroundWindow
- 设置启动activity的主题
- Activity.onCreate中设置回来原来的主题,super之前调用
启动优化相关
- 合理使用异步初始化、延迟初始化、懒加载。
- AsyncLayoutInflater:异步加载xml
- idleHandler:消息队列为空的时候再执行,比如要处理界面加载完后的操作,注意:如果要长期监听则要反射调用 改返回参数true。
- 启动过程避免耗时操作,比如数据库、i/o操作不要在主线程。
- 类加载优化:提前异步执行类加载。
- 简化布局