🕐 Revisited — 📚 A Guide on Splash Screen in Android in 2020
👀 A fresh look on the splash screen in Android in Kotlin and Coroutines
Splash screen is a very popular methodology in Android app development. Almost all major apps contain some sort of splash screen for many different reasons from brand awareness to loading heavy resources before app start. Some apps even add splash screens just because everyone else is adding it to follow the paradigm, even though their apps don’t need it.
Its a very debatable topic on whether apps should contain splash screen or not as this wastes few (important) seconds of user’s time. In this article, we will not be focusing on that debate. Rather, this topic is about technical details on creating splash screens with the modern Android development approaches followed in 2019 or upcoming 2020. So, without further ado, let’s start ordering from the old way to new way.
🎨 Using Activity Theme
When any app is launched, Android system will try to draw the first screen as fast as it can. But for the new launches, this may take few moments. During these moments, Android by default shows a empty placeholder screen filled with your app’s
windowBackgroundcolor. You can extend this placeholder from just a color to your splash screen using the
Activity theme approach.
Create a separate theme for your splash
Activity and set its
windowBackground to your custom splash drawable.
You can see that we have set
windowBackground to our splash screen drawable in file
splash_drawable.xml file. Here’s that file.
Now, set this theme to your splash
Activity in the
And this will give you an Amazon-like splash screen.
Now, whatever time Android System is supposed to show a black placeholder screen while starting up your app and allocating memory resources for it, the system will show this screen instead of that placeholder. And once your app is ready and launched, then still you will be seeing this. And your whole layout passed in
setContentView() method will be drawn on top of this screen. So, you will have to reset your original app’s theme in your
Activity . You can do this easily by adding
setTheme() before the
setContentView() method call in your
Now, as your app’s ready, it will change to your original app’s theme like the normal apps do. The code for this approach is available in the
SplashThemeActivity class at the Splash Screen Demo repository.
Overall, this approach is good from the user experience as it doesn’t waste time. It only takes time to load the app. So, if your app is already in the memory, you won’t see the splash theme much. This approach is applied in Google’s apps a lot.
But the problems with this approach are that if your splash contains fancy animations or even a simple loading progress bar, you can’t add this. You can only add an image through
<bitmap> tag in your theme and change the position of it on the screen.
If you want to add multiple starting points based on some logic, like whether to show login or the home screen, then this approach can work a little trick. Instead of setting splash theme to your home screen, create a separate dedicated
Activity for your splash and apply the theme to it. Then write your business logic in that
Activity . You can check the the code in
SplashLogicActivity.kt class at the Splash Screen Demo repository.
⏰ Using Handler / Runnable / Timer
A huge number of apps follow this approach to create splash screen. The idea is to create a separate
Activity for splash screen and then launch the main screen either fixed or based on some logic after some scheduled time of like 2–3 seconds. This splash screen doesn’t do anything except show the user some screen and make user wait for few seconds. This is achieved by commonly using the
This is quite similar to the separate
Activity with the theme approach. But we get many advantages in this method over the themed activity. You can add animations, or any sort of customizations in your layout for the splash screen. You can also add business logic to redirect user to any specific screen. But there’s a problem. The code for this is available in
CommonSplashActivity at the Splash Screen demo repository.
If the user presses the hard back button while splash screen, it won’t cancel the
Handler instance, and you will see some screen popup randomly because it was scheduled to launch. This can cause memory leak or if you’re storing some data in memory in your splash screen, then that data will be lost. Because Android system will launch your home screen as a new task.
One way to fix this is using the
Timer class because we can cancel the
Timer instance in either
onDestroy() methods to stop the scheduled launch of the home / login screens. You can get check this code in
TimerSplashActivity at the Splash Screen demo repository.
This approach will avoid you the memory leaks or the sudden popping up of the screen because timer is cancelled in
onPause() and because of it the launch of home screen task is also terminated.
It must be noted that
Timer creates a whole new thread in background. And you cannot interact with UI elements,
View objects etc. in this thread. For example, you cannot update animations of views, or change
TextView ‘s text values etc in the
TimerTask object. Memory-wise this is a heavy operation approach and due to thread-switching it can also be slow.
I have seen some places where a
Thread is used instead of timer. And
Thread.sleep() is used for delay purposes. I would highly recommend you to avoid this method as this will not only cause memory leaks and is almost similar to the previous
Handler approach we discussed.
🎯 Using Kotlin Coroutines
Yes, you read that right. I would only recommend this method if you already have Kotlin Coroutines in your project or you plan to add in near future. Because it wouldn’t be a good approach to just add Kotlin Coroutines for splash screen.
Conceptually, this is a lot similar to
Timerapproach, but we will use coroutines, instead of
Timer objects. Here’s the code for this. (You can also check this code in the
SplashActivity in the Splash Screen repository on Github.
activityScope we created is of
Dispatchers.Main , so this will run on the main UI thread. And being a coroutine, there will be no thread switching as coroutines run on the same thread. This will help in the performance speed as opposed to the
Activity gets paused or destroyed, the coroutine will be cancelled automatically. This will avoid the sudden popping of the home/login screen. And surprisingly, since this coroutine is running on
Dispatchers.Main , we can easily update UI elements, view animations etc. without any tension.
Overall, the coroutines approach is fast, reliable, less-memory consuming, gives the advantage of main UI thread access, and supports the custom launch logic.
💻 Show Me The Code
The code is available on my Github profile at Splash Screen repository. It contains all the splash screen approaches discussed in this article in separate
Activity classes. You need to launch any of the
Activity as launcher in
AndroidManifest.xml to check the behavior of that approach.
📄 Making The Decision
The best approaches are theme approach and coroutines approach.
If your app has fixed home screen, then use the splash theme on that home screen.
If your app needs business logic to decide the home screen, use the separate
Activitywith theme approach.
If your app has fancy animations and / or complex splash UI, then create a separate
Activityand use Kotlin Coroutines. If your app doesn’t intend to use Coroutines, then you should switch it the the
Handlerapproach, but be aware of the memory leaks.
Finally, do not use
Threadat all for splash screen and try to avoid