jvmsplash-screencompose-multiplatformcompose-desktopjetbrains-compose

How to show OS splash screen on startup of a Compose Multiplatform app?


JVM (Java/Kotlin) apps take a little time to start and be presented to the user.

There may be various "tricks" to show a splash screen when the app is being loaded.

My main purpose for displaying a splash screen is to show some indication that the app is being launched. So, for example, starting an launcher Java process to show an artificial splash screen may defeat the purpose because it itself may take some time to appear on the screen.

So, how can I take advantage of the OS native splash screens while my app has not yet appeared on the screen?


Solution

  • It seems Java supports showing operating system native splash screen while the app is being started.

    I only tested it on Windows and it worked as expected.

    So, in my project build.gradle(.kts) I added this:

    compose.desktop {
        application {
            nativeDistributions {
                appResourcesRootDir = rootDir.resolve("myAssets")
                // ...
            }
            // The image path is relative to the app (Java) working directory
            // which is the app installation root directory (where the .exe file resides)
            jvmArgs += "-splash:app/resources/myImage.gif"
            // To make it work whatever is the working directory when invoking the app use:
            // jvmArgs += "-splash:${'$'}APPDIR/resources/splash.png"
            // ...
        }
    }
    

    It uses the myImage.gif image placed in <PROJECT_DIR>/myAssets/common/ directory.
    See Adding files to packaged applications for more information.

    The splash screen works when the app is launched with its installed exe or one of Compose Multiplatform run*Distributable tasks. To also set the splash for application fat/uber jar (created with one of package*UberJar* tasks), copy the splash image into classpath (like src/main/resources directory) and add the code below in your build file to update all the Jar tasks:

    tasks.withType<org.gradle.jvm.tasks.Jar> {
        manifest {
            attributes["SplashScreen-Image"] = "myImage.gif"
        }
    }
    

    It seems that Windows does not respect the GIF speed and no-loop settings and plays the animation at a low frame rate. See Gif Animated Files in C# have Lower framerates than they should.

    See the related issue in Compose Multiplatform repository.