美文网首页
Android启动窗口SplashScreen

Android启动窗口SplashScreen

作者: 罗亮_13 | 来源:发表于2020-06-27 23:53 被阅读0次

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

    image-20200627223615053.png
    1596117549969.gif

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


    image-20200627224321594.png

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

    1、一般需要较长时间加载的应用启动窗口的作用更明显,所以可以实现个简单的Activity作为欢迎界面,待准备工作加载完成后,即可跳转到正式界面

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

    image-20200627224150879.png
    1596117876257.gif

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

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

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

    ActivityRecord.java-showStartingWindow

    image-20200627224821300.png

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

    image-20200627225544058.png

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

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

    image-20200627225858187.png

    其中AppWindowToken的getStartingWindowType方法逻辑如下

    image-20200627230030337.png

    从上述代码可知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信息可看到有如下窗口,这就是启动窗口的窗口,也是这里主要介绍的逻辑(如下是设置的启动窗口)

    image-20200627230345034.png

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

    image-20200627230604007.png

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

    image-20200627230838390.png

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

    image-20200627231001578.png

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

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

    image-20200627231135203.png

    再看下mAddStartingWindow的逻辑:

    image-20200627231354809.png

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

    image-20200627231547302.png

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

    image-20200627231806108.png image-20200627231853737.png image-20200627231958425.png image-20200627232221316.png

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

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

    1、windowAnimationStyle

    image-20200627232535987.png

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

    2、windowSplashscreenContent

    image-20200627232650202.png

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

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

    相关文章

      网友评论

          本文标题:Android启动窗口SplashScreen

          本文链接:https://www.haomeiwen.com/subject/jwcbfktx.html