将您的启动画面实现迁移到 Android 12 及更高版本

如果您在 Android 11 或更早版本中实现了自定义启动画面,请将您的应用迁移到 SplashScreen API,以帮助确保它在 Android 12 及更高版本中正确显示。

从 Android 12 开始,系统会对所有应用在冷启动温启动时应用Android 系统默认启动画面。默认情况下,此系统启动画面是使用应用的启动器图标元素以及主题的 windowBackground(如果它是单一颜色)构建的。

如果您不迁移应用,则应用在 Android 12 及更高版本上的启动体验可能会降低或产生意想不到的结果。

  • 如果您现有的启动画面是使用覆盖 android:windowBackground 的自定义主题实现的,则在 Android 12 及更高版本上,系统会用默认的 Android 系统启动画面替换您的自定义启动画面。这可能不是您应用预期的体验。

  • 如果您现有的启动画面是使用专用的 Activity 实现的,则在搭载 Android 12 或更高版本的设备上启动应用时,会导致启动画面重复出现:先显示系统启动画面,然后显示您现有的启动画面 activity。

您可以按照本文档所述的迁移过程来防止这些降低或意外的体验。迁移后,该 API 可以缩短启动时间,让您完全控制启动画面体验,并创建与平台上其他应用更一致的启动体验。

SplashScreen 兼容库

您可以直接使用 SplashScreen API,但我们强烈建议改用 Androidx SplashScreen 兼容库。兼容库使用 SplashScreen API,支持向下兼容,并在所有 Android 版本上创建一致的启动画面显示外观和风格。本文档使用兼容库编写。

如果直接使用 SplashScreen API 进行迁移,则在 Android 11 及更早版本上,您的启动画面看起来与迁移前完全相同。从 Android 12 开始,启动画面具有 Android 12 的外观和风格。

如果使用 SplashScreen 兼容库进行迁移,则系统会在所有 Android 版本上显示相同的启动画面。

迁移您的启动画面实现

完成以下步骤,将您现有的启动画面实现迁移到 Android 12 及更高版本。

此过程适用于您要从中迁移的任何类型的实现。如果您要从专用的 Activity 迁移,请遵循本文档中介绍的最佳实践,以调整您的自定义启动画面 ActivitySplashScreen API 还会减少由专用启动画面 activity 引入的启动延迟。

要迁移启动画面,请执行以下操作

  1. build.gradle 文件中,更改您的 compileSdkVersion 并将 SplashScreen 兼容库包含在依赖项中。

    build.gradle
    
    android {
       compileSdkVersion 31
       ...
    }
    dependencies {
       ...
       implementation 'androidx.core:core-splashscreen:1.0.0-beta02'
    }
    
  2. 创建一个以 Theme.SplashScreen 为父主题的主题。将 postSplashScreenTheme 的值设置为 Activity 必须使用的主题,将 windowSplashScreenAnimatedIcon 的值设置为 drawable 或动画 drawable。其他属性是可选的。

    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
       <!-- Set the splash screen background, animated icon, and animation
       duration. -->
       <item name="windowSplashScreenBackground">@color/...</item>
    
       <!-- Use windowSplashScreenAnimatedIcon to add a drawable or an animated
            drawable. One of these is required. -->
       <item name="windowSplashScreenAnimatedIcon">@drawable/...</item>
       <!-- Required for animated icons. -->
       <item name="windowSplashScreenAnimationDuration">200</item>
    
       <!-- Set the theme of the Activity that directly follows your splash
       screen. This is required. -->
       <item name="postSplashScreenTheme">@style/Theme.App</item>
    </style>
    

    如果要在图标下方添加背景颜色,可以使用 Theme.SplashScreen.IconBackground 主题并设置 windowSplashScreenIconBackground 属性。

  3. 在清单文件中,将启动 activity 的主题替换为上一步中创建的主题。

    <manifest>
       <application android:theme="@style/Theme.App.Starting">
        <!-- or -->
            <activity android:theme="@style/Theme.App.Starting">
    ...
    
  4. 在启动 activity 中,在调用 super.onCreate() 之前调用 installSplashScreen

    Kotlin

    class MainActivity : Activity() {
    
       override fun onCreate(savedInstanceState: Bundle?) {
           // Handle the splash screen transition.
           val splashScreen = installSplashScreen()
    
           super.onCreate(savedInstanceState)
           setContentView(R.layout.main_activity)
    ...

    Java

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
             // Handle the splash screen transition.
             SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
    
             super.onCreate(savedInstanceState);
             setContentView(R.layout.main_activity);
        }
    }

installSplashScreen 返回启动画面对象,您可以选择使用该对象来自定义动画或将启动画面在屏幕上保留更长时间。有关自定义动画的更多详细信息,请参阅将启动画面在屏幕上保留更长时间自定义关闭启动画面的动画

调整您的自定义启动画面 Activity 以适应启动画面

迁移到 Android 12 及更高版本的启动画面后,决定如何处理您以前的自定义启动画面 Activity。您有以下选项

  • 保留自定义 activity,但阻止其显示。
  • 出于品牌原因保留自定义 activity。
  • 移除自定义 activity 并根据需要调整您的应用。

阻止自定义 Activity 显示

如果您之前的启动画面 Activity 主要用于路由,请考虑如何移除它。例如,您可以直接链接到实际 activity 或迁移到带有子组件的单一 activity。如果这不可行,您可以使用 SplashScreen.setKeepOnScreenCondition 来保留路由 activity,但阻止其渲染。这样做会将启动画面转移到下一个 activity,并支持平滑过渡。

Kotlin

  class RoutingActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()
        super.onCreate(savedInstanceState)

        // Keep the splash screen visible for this Activity.
        splashScreen.setKeepOnScreenCondition { true }
        startSomeNextActivity()
        finish()
     }
   ...
  

Java

  public class RoutingActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      SplashScreen splashScreen = SplashScreen.installSplashScreen(this);

       super.onCreate(savedInstanceState);

       // Keep the splash screen visible for this Activity.
       splashScreen.setKeepOnScreenCondition(() -> true );
       startSomeNextActivity();
       finish();
    }
  ...
  

出于品牌原因保留自定义 activity

如果出于品牌原因要使用之前的启动画面 Activity,您可以通过自定义关闭启动画面的动画,从系统启动画面过渡到您的自定义启动画面 Activity。但是,最好尽可能避免这种情况,并使用 SplashScreen API 为您的启动画面打上品牌烙印。

如果您需要显示对话框,建议在后续的自定义启动画面 activity 上方或在系统启动画面之后的主 activity 上方显示它。

移除自定义启动画面 Activity

通常,我们建议完全移除之前的自定义启动画面 Activity,以避免启动画面重复,提高效率,并减少启动画面加载时间。您可以使用不同的技术来避免显示冗余的启动画面 activity。

  • 对您的组件、模块或库使用惰性加载。避免加载或初始化应用启动时不需要的组件或库。稍后在应用需要时加载它们。

    如果您的应用确实需要一个组件才能正常工作,请仅在真正需要时加载它,而不是在启动时加载,或者使用后台线程在应用启动后加载它。尽量使您的 Application.onCreate() 尽可能轻量化。

    您还可以利用App Startup 库在应用启动时初始化组件。这样做时,请确保仍然加载启动 activity所需的所有必需模块,并且不要在惰性加载模块可用时引入卡顿。

  • 在加载少量本地数据时创建占位符。使用推荐的主题方法,并延迟渲染,直到应用准备就绪。要实现向下兼容的启动画面,请按照将启动画面在屏幕上保留更长时间中概述的步骤进行操作。

  • 显示占位符。对于持续时间不确定的网络加载,关闭启动画面并显示异步加载的占位符。考虑对内容区域应用细微动画以反映加载状态。确保加载的内容结构尽可能匹配骨架结构,以便在内容加载时支持平滑过渡。

  • 使用缓存。当用户首次打开您的应用时,您可以为某些 UI 元素显示加载指示器,如下图所示。用户下次返回应用时,您可以在加载最新内容的同时显示此缓存内容。

图 1. 显示 UI 占位符。