Android启动流程优化 上篇
本文链接:Android启动流程优化 上篇_猎羽的博客-CSDN博客
启动流程
各个阶段图
1、各个阶段的概括总结
分为5个大阶段或者10个小阶段
【字节跳动团队】内部论坛分享也是这么处理的
补充一些只是细节点:
- application#onCreate()运行在主线程中,如果比较耗时,也会影响到后面Activity阶段的开始(延迟开始)
- 每个优化的具体方法可能只有几行代码,但是背后蕴藏的原理是更重要的。
启动优化架构师思想
- 理论分析 => 全局思考,对全局和优先级进行把控,不陷入到片面的细节中
- 现状分析 => 耗时分析,profile工具对可优化点摸底,确定优化方向
- 启动优化 => 具体启动优化项
- 持续测试 => 不同时期,需求不同,结合实际场景持续优化,并进行效果验证。
什么是全局思考的能力?
从整个FrameWorek的启动流程中,分析出具体可以优化的阶段和具体方法
Framework层面启动流程和原理解析
Activity启动流程
问题1:是否存在Activity启动了但是Application没有启动的情况?
存在,因为bindApplication和handleLaunchActivity,使用了非阻塞的oneway修饰的IBinder异步通信,可能存在相反情况,有保护机制:performLauncherActivity()中newActivity()后还会LoadedApk去makeApplicaiton()
黑白屏
2、黑白屏出现在哪个阶段?
- 在ActivityStarter.java startActivityInner方法中会处理黑白屏 ``
3、黑白屏属于哪个进程?
不属于App进程,在system_server进程中
4、为什么可以设置黑白屏?
该图片在AndroidManifest.xml中设置Application的主题Theme,设置了styles.xml中自定义主题的`android:windowSplashscreenContent`
5、黑白屏有什么用?
用户点击Launcher后,App启动需要时间,要给用户反馈
防止用户多次反复点击icon按钮
App启动需要时间,拦截点击事件,也避免了App的ANR
6、SystemServer和黑白屏
SystemServer本身会设置和准备Context、Theme、ActivityThread、Application
黑白屏直接由SystemServer启动
7、黑白屏启动源码解析
ActivityStarter.java#startActivityInner()
// 创建启动黑白屏window
mTargetStack.startActivityLocked
ActivityStack.java#startActivityLocked())
r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
ActivityRecord.java#showStartingWindow()
addStartingWindow(packageName, theme,
compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
allowTaskSnapshot(),
mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal());
-->mStartingData = new SplashScreenStartingData(mWmService, pkg,
theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
getMergedOverrideConfiguration());
-->scheduleAddStartingWindow();
-->mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
AddStartingWindow#run()
-->surface = startingData.createStartingSurface(ActivityRecord.this);
-->mService.mPolicy.addSplashScreen(activity.token, mPkg, mTheme, mCompatInfo,
mNonLocalizedLabel, mLabelRes, mIcon, mLogo, mWindowFlags,
mMergedOverrideConfiguration, activity.getDisplayContent().getDisplayId());
PhoneWindowManager.java#
// Obtain proper context to launch on the right display.
-->Context displayContext = getDisplayContext(context, displayId);
-->PhoneWindow win = new PhoneWindow(context);
-->addSplashscreenContent(win, context);
-->int resId = a.getResourceId(R.styleable.Window_windowSplashscreenContent, 0);
-->Drawable drawable = ctx.getDrawable(resId);
-->View v = new View(ctx);
-->v.setBackground(drawable);
-->win.setContentView(v);
-->view = win.getDecorView();
-->wm.addView(view, params);
8、android:windowSplashscreenContent App还没启动为什么可以提前拿到?
PKMS解析Apk后会解析xml文件
SystemServer需要展示黑白屏时可以直接通过ResId加载Drawable
installProvider源码解析
优化实战
1、app怎么算启动了?
点击Launcher后可以看到主界面
2、启动优化的环节在哪儿?
Launcher到App主界面区间
3、正常App启动页面分三个
Logo页面(ss)->广告页面(splash)->主页面MainActivity
4、为什么还需要广告页面?
1、赚钱
2、主页面太复杂避免黑白屏