将您的启动画面实现迁移至 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 的值设置为可绘制资源或动画可绘制资源。其他属性是可选的。

    <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. 在调用 super.onCreate() 之前,在启动 Activity 中调用 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。

  • 对组件、模块或库使用延迟加载。 避免加载或初始化应用启动时不需要的组件或库。在应用需要它们时再进行加载。

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

    您还可以受益于使用 App Startup 库在应用启动时初始化组件。执行此操作时,请务必确保仍加载启动 Activity 所需的所有模块,并且不要在延迟加载的模块变为可用时引入卡顿。

  • 在本地加载少量数据时创建占位符。 使用推荐的主题设置方法,并推迟渲染直到应用准备就绪。要实现向后兼容的启动画面,请遵循让启动画面在屏幕上保持更长时间中概述的步骤。

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

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

图 1. 显示 UI 占位符。