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

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

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

如果您不迁移您的应用,您的应用在 Android 12 及更高版本上的启动体验可能会下降或出现意外结果。

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

  • 如果您的现有启动画面是使用专用的Activity实现的,则在运行 Android 12 或更高版本的设备上启动您的应用会导致启动画面重复:系统启动画面显示后,紧跟着您的现有启动画面活动。

您可以通过完成本文档中描述的迁移过程来防止这些性能下降或意外体验。迁移后,API 可提高启动时间,让您完全控制启动画面体验,并与平台上的其他应用创建更一致的启动体验。

SplashScreen 兼容性库

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

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

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

迁移您的启动画面实现

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

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

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

  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. 在清单中,将启动活动的主题替换为您在上一步中创建的主题。

    <manifest>
       <application android:theme="@style/Theme.App.Starting">
        <!-- or -->
            <activity android:theme="@style/Theme.App.Starting">
    ...
    
  4. 在调用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主要用于路由,请考虑删除它的方法。例如,您可以直接链接到实际活动或移动到具有子组件的单个活动。如果这不可行,您可以使用SplashScreen.setKeepOnScreenCondition来保留路由活动,但阻止其渲染。这样做会将启动画面转移到下一个活动并支持平滑过渡。

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。但是,如果可能,最好避免这种情况,并使用SplashScreen API 来为您的启动画面设置品牌。

如果您需要显示对话框,我们建议在随后的自定义启动画面活动或系统启动画面后的主要活动上显示它。

删除自定义启动画面 Activity

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

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

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

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

  • 在本地加载少量数据时创建占位符。使用推荐的主题方法,并在应用程序准备就绪之前保留渲染。要实现向后兼容的启动画面,请按照延长启动画面显示时间中概述的步骤操作。

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

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

图 1. 显示 UI 占位符。