Search code examples
androidandroid-layoutsplash-screen

Android - Cold Start - How to avoid white screen opening app


In the development of the app I am encountering this problem which has already been discussed in numerous other posts but which have not given me any solution. In particular I am implementing a custom splash screen. It's custom because I don't want to show a static image as a splash but an animation.

In particular, I'm using Lottie as a library for animations, and therefore the "classic" way of creating a Theme in the Style and calling it in the OnCreate method before the super etc. etc. I don't need it, I want to go directly into the SpashActivity.

The problem is that however I can't start the app without the two seconds of white screen. I don't want to change color I just want to avoid it and go directly to the Splash activity. Anyone have any suggestions? I have already tried several ways, I put some of them below:

Things I've tried but that DON'T work:

<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>

adding the following stuff inside AndroidXml

android:theme="@android:style/Theme.Translucent.NoTitleBar"

this way freeze my screen:

<item name="android:windowDisablePreview">true</item>

Solution

  • I ran into this same issue. Currently, the only way to reduce this cold start screen time is to reduce the number of things that first screen is loading or to load them while other things are showing (asynchronously). That is outside the scope of this answer, so the workaround is to show the app logo or some image while it loads. These steps should accomplish that.

    1 - Make a background

    If you don't have a black background object, create a file named background_black.xml in the /res/drawable folder. Put this code in it:

        <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <solid android:color="@android:color/black" />
        </shape>
    

    Optional: You could also use an image, but it must be a non-animated bitmap. To do this, INSTEAD of the code above, use something like this:

        <?xml version="1.0" encoding="utf-8"?>
        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
            <!-- Base background color -->
            <item>
                <color android:color="@color/black"/>
            </item>
        
            <!-- Logo centered on the screen -->
            <item>
                <bitmap
                    android:src="@drawable/logo"
                    android:gravity="center" />
            </item>
        </layer-list>
    

    Ideally, to avoid code confusion the image background code (above) would be in a file named something like background_splash_screen.xml and you would have to use that name anywhere background_black is used below. Using this method you would also need to import your logo or image into /res/drawable, then either name it logo or change logo in the XML above to the name of your image.

    A good idea is also to be sure you have versions of the image in sizes that match what your users are likely to see, but importing using Android Studio should take care of that for you. I tested importing on Giraffe (version 2022.3.1) of Android Studio. On that version the option was in File >> New >> Image Asset.

    To do this manually, put the correctly-sized version of the image in the /res folders drawable-mdpi, drawable-hdpi, drawable-xhdpi, drawable-xxhdpi, and drawable-xxxhdpi.

    2 - Add the background to your Theme

    In res/values/themes.xml make sure you have

        <style name="AppTheme" parent="Theme.Material3.DayNight">
            <!-- Other theme attributes -->
            <item name="android:windowBackground">@drawable/background_black</item>
        </style>
    

    Make sure you change AppTheme to the name of the theme you are using. Also, make sure the parent matches the theme in your AndroidManifest.xml (more below).

    An important caution from the docs:

    If you're styling your app and not seeing the results you expect, it's likely that other styling is overriding your changes.

    If you have multiple themes you can use theme inheritance to make them work together.

    3 - Make sure your theme is in the Android Manifest

    In AndroidManifest.xml either set the global app theme

    <application
        android:theme="@style/AppTheme"
        >
    </application>
    

    or set the theme for your startup screen

    <activity
        android:name=".YourLaunchActivity"
        android:theme="@style/AppTheme"
        >
    </activity>
    

    Of course, for either option make sure you add any other settings you may need. For example, for application you might also need android:icon="@mipmap/ic_launcher" and android:label="@string/app_name". Or for the activity you might need a label like android:label="@string/title_app_activity" to help with localization. Of course you would need to set the text for both app_name and title_app_activity in your strings.xml file (currently by default in the /res/values/ folder).

    'Workarounds' NOT to use

    Do not use windowDisablePreview. It increases start time and prevents interaction with no feedback to the user. From the docs:

    You may see extra time added during startup if you have previously used one of the following methods to implement a custom splash screen in Android 11 (API level 30) or lower:

    Using the windowDisablePreview theme attribute to turn off the initial blank screen drawn by the system during launch. Using a dedicated Activity. Starting with Android 12, migrating to the SplashScreen API is required. This API enables a faster startup time, and also allows you to tweak your splash screen

    Do not use

    <item name="android:windowIsTranslucent">true</item>
    

    Based on answers to other posts about this question, it can crash the app or make objects untargetable.

    Do not use

    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    

    This can cause unexpected issues.

    These code snippets could be useful in other situations, but for fixing this cold start screen they often cause problems.