1 APP启动流程
①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起,startActivity请求;
②system_server进程接收到请求后,向zygote进程发送创建进程的请求;
③Zygote进程fork出新的子进程,即App进程;
④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
⑦主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法。
⑧到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面
2 与app开发者有关的阶段总结
2.1 进程fork阶段
2.2 Application 的启动阶段
bindApplication
1)ActivityThread.main
2)handleBindApplication
attachBaseApplication
1)4.x 之前的multidex加载优化
2)加固热修复导致延迟
installProvider
1)开源库中的Provider初始化
2)自己项目的provider初始化
application:onCreate
1)优化最大的部分,异步,按需加载,懒加载
2.3 Handle间隙
监控主线程的相关消息对主线程消息进行优化
2.4 Activity阶段
Activity启动流程
Activity显示
Activity onCreate
1)XML文件解析,反射
2)异步并发构建Viewtree
View构建
1)将Inflate过程最大异步化
1)View的度量布局和显示
View显示
2)层级优化
3)布局优化
2.5 数据的加载
1)数据预加载
2)数据缓存机制
3)显示数据加载优先级调度
2.6 黑白屏
1 黑屏原因
-
启动时间过长:
Application初始化耗时太长。- 资源加载阻塞主线程。
protected attachBaseContext(Context base){
}
@Override
public void onCreate(){
super.onCreate();
// 这里的逻辑过于复杂,耗时多
}
- 第一个activity 的onCreate(),onStart(),onResume() 里面耗时
override fun onCreate() {
super.onCreate()
// 这里的逻辑过于复杂,耗时多
}
override fun onStart() {
super.onStart()
// 这里的逻辑过于复杂,耗时多
}
override fun onResume() {
super.onResume()
// 这里的逻辑过于复杂,耗时多
}
3. Theme 配置问题:
* 启动时未设置合适的窗口背景(Window Background)。
* 使用了默认的黑色主题。
2 白屏原因
-
默认窗口背景:
- 系统默认的
WindowBackground主题颜色为白色,启动时未修改。
- 系统默认的
-
首次布局渲染缓慢:
setContentView的布局复杂,导致渲染时间过长。- 布局加载图片资源或网络资源。
3 解决方案
(1) 设置启动主题背景
通过设置 WindowBackground,避免黑白屏出现。
具体实现:
在 res/values/styles.xml 中添加启动主题:
xml
复制代码
<style name="AppTheme.Launcher" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 设置启动背景 -->
<item name="android:windowBackground">@drawable/splash_screen_background</item>
<!-- 禁用 ActionBar -->
<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
-
常见配置:
@drawable/splash_screen_background可以是简单的颜色或图片资源。- 如果需要渐变背景,可以使用
@drawable/gradient_background。
在 AndroidManifest.xml 中将此主题应用于启动 Activity:
xml
复制代码
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
(2) 动态切换主题
当 Activity 完成初始化后,切换回应用的主主题。
实现方法:
kotlin
复制代码
override fun onCreate(savedInstanceState: Bundle?) {
// 切换到正常主题
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
(3) 优化 Application 和 Activity 初始化
-
减少初始化操作:
- 将一些不必要的初始化延迟到后台线程。
- 使用
WorkManager或HandlerThread处理非关键任务。
-
避免阻塞主线程:
- 避免在
onCreate中执行复杂的逻辑或长时间 IO 操作。 - 优化
ContentProvider的加载。
- 避免在
-
Lazy Load 机制:
- 对资源加载和依赖初始化采用懒加载策略,按需加载。
(4) 简化布局文件
-
优化布局结构:
- 避免嵌套过深的
LinearLayout,可以使用ConstraintLayout替代。通过Chain等功能,完全可以在一个ConstraintLayout里实现。层级减少,意味着渲染性能提升,官方的数据是渲染速度比RelativeLayout提高大约40%。 - 使用
ViewStub对延迟显示的视图进行优化。
- 避免嵌套过深的
-
预加载资源:
- 预加载启动必要的图片和字体,避免布局解析等待。
(5) 使用 Splash Screen API
从 Android 12 开始,Google 提供了专用的 Splash Screen API,可用于优雅地显示启动画面。
配置方法:
-
添加
SplashScreen依赖:gradle 复制代码 implementation "androidx.core:core-splashscreen:1.0.0" -
在
AndroidManifest.xml配置:xml 复制代码 <activity android:name=".MainActivity" android:exported="true" android:theme="@style/Theme.App.SplashScreen"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> -
自定义启动背景: 在
res/values/themes.xml配置:xml 复制代码 <style name="Theme.App.SplashScreen" parent="Theme.SplashScreen"> <item name="windowSplashScreenBackground">@color/splash_background</item> <item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_icon</item> <item name="windowSplashScreenIconBackgroundColor">@color/icon_background</item> <item name="postSplashScreenTheme">@style/AppTheme</item> </style>
4. 常见问题排查
-
黑屏仍然存在:
- 检查是否未正确设置
windowBackground。 - 确保未执行耗时操作。
- 检查是否未正确设置
-
白屏出现时间过长:
- 优化布局文件。
- 检查图片资源加载时间。
-
闪屏后仍有卡顿:
- 优化启动逻辑,减少
onCreate中的复杂操作。
- 优化启动逻辑,减少
3 view 显示相关
3.1 activity与 PhoneWindow与DecorView关系
3.2 View 层级结构
对应于ViewRootImpl(替代ViewRoot)类,它是连接WindowManager和DecorView的纽带的三大流程均是通过ViewRoot完成的。当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象和DecorView建立关联