将启动画面实现迁移到 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 compat 库

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

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

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

迁移启动画面实现

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

此过程适用于要从中迁移的任何类型的实现。如果您要从专用 Activity 进行迁移,请按照本文档中所述的最佳实践来调整自定义启动画面 ActivitySplashScreen API 还可以降低通过专用启动画面 activity 引入的启动延迟时间。

如需迁移启动画面,请执行以下操作:

  1. build.gradle 文件中,更改 compileSdkVersion 并在依赖项中添加 SplashScreen compat 库。

    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. 在启动 activity 中,先调用 installSplashScreen,然后再调用 super.onCreate()

    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 所需的所有模块,并且不会在延迟加载的模块可用时引入卡顿。

  • 在本地加载少量数据时创建占位符。请使用推荐的主题方法,并在应用准备就绪之前暂缓渲染。如需实现向后兼容的启动画面,请按照让启动画面在屏幕上显示更长时间中列出的步骤操作。

  • 显示占位符。对于基于网络的加载(持续时间不确定),请关闭启动画面并显示异步加载占位符。考虑在内容区域应用巧妙的动画效果来反映加载状态。确保加载的内容结构与框架结构相符,并尽可能支持内容加载时的平滑过渡。

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

图 1.显示界面占位符。