Search code examples
androidandroid-12android-splashscreen

Android 12 Splash Screen API inconsistent behavior


I am implementing the new Splash Screen API but encountered an inconsistent behavior on it. Sometimes the screen with app icon shows and sometimes it doesn't. There is also a long white screen on the beginning which is visibly annoying (The attached image was just speed up 3x since I cannot upload image file higher than 2mb here, but the white screen was clearly visible for a couple of seconds and Splash API seems to cause frame skip from Choreographer log).

Samsung J1 Android L

enter image description here

class LauncherActivity : AppCompatActivity() {

private var keepSplash = true

private lateinit var splashScreen: SplashScreen

override fun onCreate(savedInstanceState: Bundle?) {

        splashScreen = installSplashScreen().apply {
            // Behaves like observable, used to check if splash screen should be keep or not
            setKeepOnScreenCondition {
                keepSplash
            }
            setOnExitAnimationListener { sp ->
                sp.remove() // Remove splash screen
            }
        }

        super.onCreate(savedInstanceState)

}

fun fetchData() { 
   //Fetching network data... 
   keepSplash = false
}

Showing the AlertDialog seems not working unless I minimize the app and reopen it with setKeepOnScreenCondition. It seems to block the UI thread, is there other way to retain the splash but not a blocking UI one? Currently we need to show an AlertDialog if something went wrong but at the same time the splash screen will be retain until the dialog is dismiss.


Solution

  • I solved the issue, first if you want to keep the splash icon screen on user screen you need to use both setKeepOnScreenCondition and setOnExitAnimationListener

    splashScreen.apply {
                // Behaves like observable, used to check if splash screen should be keep or not
                setKeepOnScreenCondition {
                    keepSplash // True to keep the screen, False to remove it
                }
                setOnExitAnimationListener { splashScreenViewProvider ->
                    // Do nothing so the splash screen will remain visible
                }
            }
    

    or just

    splashScreen.setOnExitAnimationListener {
    
                // Do nothing so the splash screen will remain visible
                splashScreenViewProvider = it
    
            }
    

    Then just call splashScreenViewProvider.remove() later when you are done.

    Just remember that setKeepOnScreenCondition can be a UI blocking thread so if ever you are fetching some data during splash screen and showed an error message via dialog, Toast, or SnackBar it wont work. You need to set setKeepOnScreenCondition to false first.

    The role of empty setOnExitAnimationListener here is not to remove the splash screen even after setting a false condition on setKeepOnScreenCondition.

    UPDATED

    It is probably best to just use and empty setOnExitAnimationListener if you want to control and extend the Splash Screen. Then save its splashScreenViewProvider in a variable and use it later to control or dismiss the screen by calling remove(). Documentation is here.

    There might times where the splash logo may not show due to how it works with hot start and cold start. https://developer.android.com/develop/ui/views/launch/splash-screen#how

    Note that there still issue when installing and running the app directly using USB debugging in Android Studio where the SplashScreen never showed up and stuck in empty screen which can be problematic when you are using Firebase Test Lab. The issue only happens in SDK 31 and 32.

    https://issuetracker.google.com/issues/197906327