Android启动窗口SplashScreen

Android启动窗口SplashScreen

首先介绍下什么是启动窗口,对于大部分应用冷启动时的场景都会有启动窗口,为了让效果更明显,在如下代码中(只是一个基本的可以运行的应用即可)添加了sleep5s的代码,在按recent键移除应用后,再点击桌面图标,即可看到启动窗口效果,即使点击后界面内容显示出来前的白色界面


启动窗口有什么用途呢,从逻辑及效果看,其应该主要是用于一个过渡,比如上述添加了5s延时的场景中,如果没有启动窗口,那么点击了桌面的应用图标后,会有5s多的时间用户看不到什么反应,会让用户觉得是不是应用没启动啊,我们可以试验下,可在style中添加
true
项,即可禁用启动窗口,如

对用户和应用来说一个白色界面作为启动窗口可能不是很美观,也可以做一些自定义行为

1、一般需要较长时间加载的应用启动窗口的作用更明显,所以可以实现个简单的Activity作为欢迎界面,待准备工作加载完成后,即可跳转到正式界面,这里使用Activity可能较慢,也可以自己实现窗口,如在application中启动时使用windowmanager的addView接口添加一个自己实现的窗口,在加载完成后将其移除即可

2、启动窗口界面内容本身有配置的方法,可通过配置<item name="android:windowSplashscreenContent"> </item>
项来设置启动窗口的内容界面,显然这里可设置一个drawable,在添加启动窗口界面时,会将该drawable添加到启动窗口的内容视图中,如

另外可通过设置<item name="windowAnimationStyle"> </item>来设置相关动画,这里就不举例了

添加启动窗口逻辑(使用android-10.0.0_r39分支代码)

(添加时机,一般是前台task切换时可能会触发,比较特别地是一般新启动一个应用,或杀掉一个应用进程后启动该应用时,这种情况下一般都会有启动窗口,如设置、电话等应用新启动时,会先显示一个空白的界面,然后显示设置界面内容,那个空白的界面即其启动窗口)

ActivityRecord.java-showStartingWindow

在这里会调用其addStartingWindow方法(ActivityRecord)

显然,这里主要是调用了AppWindowToken的addStartingWindow方法,查看AppWindowToken的addStartingWindow方法,这里逻辑稍多,介绍下其主要部分

1、该方法中会调用getStartingWindowType方法根据场景获取需要启动窗口类型

其中AppWindowToken的getStartingWindowType方法逻辑如下

getStartingWindowType方法可能返回三种值 STARTING_WINDOW_TYPE_NONE,STARTING_WINDOW_TYPE_SPLASH_SCREEN 和 STARTING_WINDOW_TYPE_SNAPSHOT

看其逻辑返回类型为STARTING_WINDOW_TYPE_NONE时应该是无启动窗口的

返回类型为STARTING_WINDOW_TYPE_SPLASH_SCREEN时即可能会有场景中的启动窗口,比如在杀掉设置进程后(点击recent导航键,移除设置),点击设置图标后马上dumpsys window信息可看到有如下窗口,这就是启动窗口的窗口,也是这里主要介绍的逻辑(如下是设置的启动窗口)

返回类型为STARTING_WINDOW_TYPE_SNAPSHOT时,会调用createSnapshot方法,这里也会临时添加一个特殊的窗口,比如进入设置后,回到桌面,点击recent导航键,然后点击,这里就不细将了

2、如果theme中设置了windowIsTranslucent为true,或者设置了windowIsFloating为true,或者设置了windowDisablePreview为true,则不会添加启动窗口

3、AppWindowToken的addStartingWindow方法的主要逻辑会创建一个SplashScreenStartingData对象,然后调用scheduleAddStartingWindow方法

AppWindowToken的addStartingWindow方法就到这里了,继续跟踪其主要逻辑

scheduleAddStartingWindow方法主要是将一个mAddStartingWindow任务放到一个handler队首去执行

再看下mAddStartingWindow的逻辑:

这里mStartingData即是前面addStartingWindow中创建的SplashScreenStartingData对象(只针对这里STARTING_WINDOW_TYPE_SPLASH_SCREEN的情况),这里主要逻辑即调用SplashScreenStartingData的createStartingSurface方法

显然,SplashScreenStartingData的createStartingSurface方法中调用了PhoneWindowManager的addSplashScreen方法而PhoneWindowManager的addSplashScreen方法也即是添加启动窗口的地方

如上即是PhoneWindowManager的addSplashScreen方法的代码,其主要部分就是创建一个PhoneWindow对象,然后设置些属性和视图(基本上应该是全屏,内容应该是根据theme相关只有框架的界面,具体内容一般为空白,有的有图标和标题),然后调用WindowManager服务的addView方法添加窗口

这里也有几个可设置相关属性的地方

1、windowAnimationStyle

应该可以通过设置windowAnimationStyle设置相关动画

2、windowSplashscreenContent

根据启动窗口调用的addSplashscreenContent方法,应该可以通过设置windowSplashscreenContent属性来设置启动窗口的内容图片

在添加启动窗口呼,待合适的时机,如应用界面绘制完成则会触发AppWindowToken的removeStartingWindow方法调用,然后移除启动窗口,这里就不细述了

posted @   luoliang_13  阅读(225)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示