Site icon The Winter Blog

Splashing around

I’m interviewing at one of my dream workplaces. To prepare for the first interview, I started looking at their repositories on Github. Since I enjoy learning by doing, I decided to look if they have any easy outstanding issues. They did. They even helpfully marked them as ‘good first issue.’ That’s how I landed up on the task at hand.

A user reported that even when his app was set to dark mode, when opening, it first created an all white flash screen, before opening the activity in dark mode. A team member had suggested that they probably didn’t have the correct background colour resource for dark mode. Seemed like a trivial fix, so I decided to look into it.

After a bit of digging around, it became clear that this wasn’t the cause. The theme and colours had been setup properly. The flash was occurring before the theme was even applied.

They were setting the night mode at the beginning of the activity. The recommendation is to set it in the application class. My guess was that this was causing the issue. But I couldn’t replicate the issue, so I couldn’t really test if this was really the cause. Nonetheless, I made the change and sent in a PR, stating that I didn’t know if this was really the cause.

The team member had a look and reported that the bug was still occurring. He also gave detailed instructions on creating the bug. He may have also suggested that it was a low priority bug not worth spending much time on. But, now that I had a way to reproduce the bug, I had to give it another go.

This time I got the diagnosis correct. The bug occurs not because the theme is not applied. It occurs that when an app is launched, the system always creates a splash window for it. For this splash, the system uses the windowBackground attribute in the app’s default theme. If there are day/night variants, it applies the variant according to current system night mode. Not according to the app’s specified night mode.

This difference between the system and app night mode was what created the unique condition for this issue. It only occurs when the system night mode is different from the app’s night mode. Moreover it never appears when the night mode is set to ‘Follow system’ in the app. Which is why I had been unable to replicate it.

Now that I knew the cause, there were two clear solutions:

  1. Set an attribute in the app theme to hide the splash window:
    <item name="android:windowDisablePreview">true</item>
    This approach is very simple. But it produces a visible delay between the user pressing the app button, and the app window actually appearing.
  2. Create a special splash theme with a background that appears neutral on  both night and dark theme.
    I use this in my Todo.txt app—background in primary colour with the app icon on it. I recommended this approach.

After another round of feedback, I created a new theme for their app with brand colour as background and a clear white logo centered on screen. I set it as the default application theme, and added the actual app theme to the individual activities. Works like a charm.

I’ve updated the code and am ready to send in another PR. Their team is having a discussion on size of the logo—I’d set it at 96dp, the designer wanted to check how 72dp looked. (I now prefer the 72dp logo.) Once that is confirmed, I’ll update the size and send the PR.


Side effects

Working on that introduced me to two changes I needed to make to my apps.

Todo.txt uses a green splash screen that works (mostly) in both dark and light modes. However, I use a special Splash Activity to with this theme. The activity doesn’t have any content. It’s just there to ensure the splash theme is used. It just forwards all launch intents to the Main Activity.

My first intent was to just update the manifest with splash theme as the default application theme, and the actual app theme as default theme for various activities. Sadly, the system is smart. If both the application and the launch activity have a theme, it ignores the application theme and just uses the activity theme. Which means no splash :(

I have now set the Splash theme as the default application theme in the manifest. Next, I created a base ThemedAppCompatActivity from which all my applications extend. All that this activity does is to apply the actual app theme. It uses the old default theme. A child activity can override the themeId variable with another theme’s id to use it. Simples. These changes allowed me to get rid of the SplashActivity. (Code deletion dance! Yay!)

AcceleReader for Instapaper uses night mode specific splash screen. A light or dark background with the pink app icon centered in it. Now that I know the special case of the original issue, I verified that AcceleReader suffers from it as well. Set the app theme to dark and the system theme to light. Open the app. It shows the light mode splash screen before opening the app in dark mode.

I need to change this to a single splash screen irrespective of night mode. Just need to find the right colour. I don’t think a full pink screen will work :)


tldr: System uses system night mode to create splash screen, not the app’s specified night mode. This causes an issue when app and system are in different night modes. To rectify, specify a single splash theme with a neutral windowBackground that works in both day and night mode.

Exit mobile version