If you have previously implemented a custom splash screen in Android 11 or
lower, you’ll need to migrate your app to the
SplashScreen
API to ensure that it
displays correctly in Android 12 and higher.
Starting in Android 12, the system always applies the new Android system
default splash screen on
cold and
warm starts for all apps.
By default, this system default splash screen is constructed using your app’s
launcher icon element and the
windowBackground
of your
theme (if it's a single color).
If you do not migrate your app, your app launch experience on Android 12 and higher will be either degraded or may have unintended results:
If your existing splash screen is implemented using a custom theme that overrides
android:windowBackground
, the system replaces your custom splash screen with a default Android system splash screen on Android 12 and higher (which may not be your app’s intended experience).If your existing splash screen is implemented using a dedicated
Activity
, launching your app on devices running Android 12 or higher results in duplicate splash screens: the new system splash screen displays, followed by your existing splash screen activity.
You can prevent these degraded or unintended experiences by completing the migration process described in this guide. Once you migrate, the new API improves startup time, gives you full control over the splash screen experience, and ensures a more consistent launch experience with other apps on the platform.
SplashScreen compat library
You can use the SplashScreen
API directly, but we strongly recommend using the
Androidx SplashScreen
compat library
instead. The compat library uses the SplashScreen
API, enables
backward-compatibility, and creates a consistent look and feel for splash screen
display across all Android versions. This guide is written using the compat
library.
If you choose to migrate using the SplashScreen API directly, on Android 11 and lower your splash screen looks exactly the same as it did before; starting on Android 12, the splash screen will have the new Android 12 look and feel.
Migrate your splash screen implementation
Complete the following steps to migrate your existing splash screen implementation to the new experience for Android 12 and higher.
This procedure applies to whichever type of implementation you are migrating
from. If you’re migrating from a dedicated Activity
, you should also follow
the best practices described on this page for adapting
your customized splash screen Activity
. The new SplashScreen
API also
reduces startup latency that was introduced with a dedicated splash screen
activity.
After you migrate using the SplashScreen
compat library, the system displays
the same splash screen on all versions of Android.
To migrate your splash screen:
In the
build.gradle
file, change your compileSdkVersion and include theSplashScreen
compat library in dependencies.build.gradle android { compileSdkVersion 31 ... } dependencies { ... implementation 'androidx.core:core-splashscreen:1.0.0-beta02' }
Create a theme with a parent of
Theme.SplashScreen
, and set the values ofpostSplashScreenTheme
to the theme that theActivity
should use andwindowSplashScreenAnimatedIcon
to a drawable or animated drawable. The other attributes are optional.<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 either 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. --> <!-- Required --> <item name="postSplashScreenTheme">@style/Theme.App</item> </style>
If you want to add a background color underneath your icon, you can use the
Theme.SplashScreen.IconBackground
theme and set thewindowSplashScreenIconBackground
attribute.In the manifest, replace the theme of the starting activity to the theme you created in the previous step.
<manifest> <application android:theme="@style/Theme.App.Starting"> <!-- or --> <activity android:theme="@style/Theme.App.Starting"> ...
Call
installSplashScreen
in the starting activity before callingsuper.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
returns the splash screen object, which you can optionally
use to customize animation or keep the splash screen on screen for a longer
duration. For more details on customizing the animation, see
Keep the splash screen on-screen for longer
periods
and Customize the animation for dismissing the splash
screen.
Adapt your custom splash screen Activity to the new splash screen experience
After you've migrated to the new splash screen experience for Android 12 and
higher, and your custom splash screen Activity
is still left over, you’ll need
to choose what to do with it. You have the following options:
- Keep the custom activity, but prevent it from displaying
- Keep the custom activity for branding reasons
- Remove the custom activity, and adapt your app as needed
Prevent the custom Activity from displaying
If your existing splash screen Activity
is primarily used for routing,
consider ways to remove it; for example, you might directly link to the actual
activity or move to a singular activity with subcomponents. If this isn't
feasible, you can use SplashScreen#setKeepOnScreenCondition
to keep the routing activity in place but stop it from rendering.
Doing so transfers the splash screen to the next activity and allows for a
smooth transition.
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(); } ...
Keep the custom activity for branding
If you want to use a subsequent splash screen Activity
for a branding
experience, you can transition from the system splash screen into your custom
splash screen Activity
by customizing the animation for dismissing the splash
screen.
However, it’s best to avoid this scenario if possible and use the new
SplashScreen
API to brand your splash screen.
If you need to display a dialog, we recommend displaying it over the subsequent custom splash screen activity or over the main activity after the system splash screen.
Remove the custom splash screen Activity
Generally, we recommend removing your customized splash screen Activity
altogether to avoid the duplication of splash screens from not migrating,
increase efficiency, and reduce splash screen loading times. There are different
techniques that you can use to avoid showing redundant splash screen activity.
Lazy load your components, modules, or libraries: Avoid loading or initializing components or libraries that are not required for the app to work at launch, and load them later when the app needs it.
If your app truly needs a component to work properly, load it only when it’s really needed and not at launch time, or use a background thread to load it after the app has started. Try to keep your
Application onCreate()
as light as possible.You can also benefit from using the App Startup library to initialize components at application startup. When doing so, make sure to still load all the required modules for the starting activity and don’t introduce janks where the lazily loaded modules become available.
Create a placeholder while loading a small amount of data locally: Use the recommended theming approach and hold back the rendering until the app is ready. To implement a splash screen that is backward-compatible, follow the steps outlined in Keep the splash screen on-screen for longer periods.
Show placeholders: For network-based loads with indeterminate durations, dismiss the splash screen and show placeholders for asynchronous loading. Consider applying subtle animations to the content area that reflect the loading state. Make sure that the loaded content structure matches the skeleton structure as well as possible, to allow for a smooth transition, once the content is loaded.
Use caching: When a user opens your app for the first time, you can show loading indicators for some UI elements (shown in the following example). The next time a user returns to your app, you can show this cached content while you load more recent content.
Figure 1. Showing UI placeholders.