Android 12 SplashScreen API以及Jetpack兼容库

前言

1、什么是Android的冷启动时间?

冷启动时间是指点击桌面LOGO那一刻起到启动页面的Activity调用onCreate()之前的时间段。

2、冷启动的时间段内发生了什么?

在一个Activity打开时,如果Application还没有启动,系统会创建一个进程,进程的创建和初始化会消耗一些时间,在这个时间中,WindowManager会先加载APP的主题样式里的窗口背景(windowBackground)作为预览元素,然后才会真正的加载布局,如果这个时间过长,会给用户造成一种错觉:APP卡顿不流畅

常见做法

  • 将背景设置为APP Logo,市面上大部分APP都是这么做的

  • 将背景设置为透明色,当点击桌面LOGO时并不会立即启动APP,而是在桌面停留一会(其实已经启动)

上面做法可以达到秒开效果,但属于掩耳盗铃

Android 8.0

Google以前不推荐使用闪屏的使用,但是后来很多APP都在使用闪屏,Google希望让启动屏的制作更简单。

Android Oreo中提供了Splash Screen API,允许开发者把一个drawable资源设置为闪屏。

新建values-v26目录:

通过windowSplashscreenContent设置的drawable资源将会覆盖在windowBackground顶部,在系统状态栏之下,如果不想受到System Bars限制,请使用全屏主题。

如未设置windowSplashscreenContent,系统仍会使用其他属性来展示闪屏页,如:windowBackground

缺点

  • 无法定义动画
  • 无法控制时长

windowBackground设置时机

以<Android API 30 Platform>为例

PhoneWindowManager

Android 12

Android12 增加了全新的SplashScreen API,可以为所有应用启用新的启动画面,包括启动时的应用运动、显示应用图标的启动画面,以及向应用本身的过渡。

工作原理

当用户启动应用,且应用进程未在运行(冷启动)或Activity尚未创建(温启动)时:

  • 系统使用主题和自定义的动画来显示启动画面
  • 当应用准备就绪时,会关闭启动画面并显示应用

热启动不会显示启动画面。

动画元素和机制

由窗口背景、动画形式的应用图标和图标背景组成:

  • 应用图标(1)应该是矢量可绘制对象,也可以是静态或动画,动画图标会在启动画面显示时自动播放,时长不受限制,但建议不要超过1000毫秒,默认使用Launcher图标
  • 图标背景(2)是可选的,在图标与窗口背景之间需要更高的对比度时很有用
  • 窗口背景(4)由不透明的单色组成

启动画面动画由进入动画和退出动画组成:

  • 进入动画由系统控制,不可自自定义
  • 退出动画可自定义,可访问SplashScreenView以及ICON,可以设置任意动画(位移、透明度、颜色等),需要在动画执行完毕时手动移除启动画面
自定义启动画面

新建values-v31目录

让启动画面在屏幕上显示更长时间

当应用绘制第一帧后,启动画面会立即关闭。如果需要异步加载少量数据,可以使用ViewTreeObserver.OnPreDrawListener让应用暂停绘制第一帧。

自定义退出动画

可以通过getSplashScreen() 来自定义退出动画

向中心缩小退出

ICON上滑退出

Jetpack SplashScreen

Jetpack发布了androidx.core:core-splashscreen:1.0.0 以向后兼容新的 Splash Screen API,此Alpha版本包含向后移植到API 23的所有新API,图标背景除外,全球的Android设备中6及以上的版本占用率达到了9成以上。

如需了解更多信息,请参阅 androidx.core.splashscreen

关键API 说明
SplashScreen Jetpack版获取定制启动画面入口的类
installSplashScreen() 获取定制入口的静态成员函数
setKeepVisibleCondition 指定保持启动画面展示的条件
KeepOnScreenCondition 实现展示条件的接口
setOnExitAnimationListener 监听启动画面的退出时机
OnExitAnimationListener 启动画面退出的回调接口
SplashScreenViewProvider 定制退场效果的启动画面视图
Attr对比 Jetpack Android 12
指定目标Activity主题 postSplashScreenTheme -
指定动画ICON windowSplashScreenAnimatedIcon android:windowSplashScreenAnimatedIcon
指定启动画面背景 windowSplashScreenBackground android:windowSplashScreenBackground
指定Icon动画时长 windowSplashScreenAnimationDuration android:windowSplashScreenAnimationDuration
指定Icon背景 - android:windowSplashScreenIconBackgroundColor
指定品牌Logo - android:windowSplashScreenBrandingImage
API对比 Jetpack Android 12
启动画面定制入口 class androidx.core.splashscreen.SplashScreen interface android.window.SplashScreen
入口实例获取 Activity#installSplashScreen() Activity#getSplashScreen()
启动画面视图 SplashScreenViewProvider SplashScreenView

退场部分,无论是否运行在12,Jetpack SplashScreen都能达到Android 12同等效果,但进场部分在低版本存在一些局限:

  • 暂时不支持ICON动画:AnimatedVectorDrawable
  • 暂时不支持ICON背影:IconBackgroundColor
  • 暂时不支持品牌LOGO:BrandingImage

面向低版本的进场效果本质是一个LayerDrawable,无法支持Vector Drawable动画、Adaptive Icon背景。

导入依赖

基础主题配置

Android 12主题配置

Manifest配置

初始化

通过installSplashScreen() 获取SplashScreen实例,installSplashScreen() 必须先用setContentView调用,原因是install函数会获取postSplashScreenTheme 配置的主题,并在检查通过后setTheme 给Activity。

让启动画面在屏幕上显示更长时间

自定义退出动画

启动画面对比
Android 6 Android 12

遇到的问题与建议

  • Android 5.0 ~ Android 11.0系统,都统一使用android:windowBackground配置启动页背景,使用背景颜色的话,界面过于单调,效果不佳。

  • Android 12.0 如果UI设计师给你做了矢量图,你可以做动态的中心图标,不给你,使用静态图标也可以的。

  • 不要假定 splashScreen.setOnExitAnimationListener 一定会被调用
    如果业务代码写在这个函数回调中去启动应用的主界面,会发现使用调试器启动应用,则应用会一直卡在启动画面。跟踪之后,会发现 OnExitAnimationListener 并没有被调用。
    这个问题的原因是:只有从桌面启动的应用,才会主动去触发启动过场动画,而且这个动画是可选的,桌面也可以选择不触发启动过场动画。通过调试器打开的应用,是使用ADB命令启动的。这种情况下,是没有启动过场动画的,自然收不到过场动画的结束通知。
    解决这个问题的办法,就是把初始化完成的判断代码移动到 compatSplashScreen.setKeepVisibleCondition 函数中,系统会每隔200MS回调一次,直到返回 false 为止。这样我们可以在这个函数中检查一下必要的初始化是否已经完成,如果已经完成了,返回 false 即可。

  • 使用 splashScreen.setOnExitAnimationListener 设置了启动动画之后,一定要在合适的时机,主动调用 SplashScreen.OnExitAnimationListener(SplashScreenViewProvider splashScreenViewProvider)splashScreenViewProvider.remove,否则,可能会一直卡住在启动页面。(注意,只是可能,目前测试发现,不调用,不一定会卡住)。

  • 已知,在 小米 Mi 10 Android 13 Miui 14.0.2 系统上,如果启用了兼容库,但是不设置 android:windowSplashScreenAnimatedIcon 则应用会一直卡住在启动页面。

参考链接


发布者

《Android 12 SplashScreen API以及Jetpack兼容库》上有2条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注