expo: Duplicate splash screens on Android 12 with expo-splash-screen; upgrade to new Splashscreen API required?

Summary

Seems like this might go hand-in-hand with an upgrade to Android SDK 31, but didn’t see it already on the issues list, so figured I’d get it on the board just in case that it looks like expo-splash-screen would need to be updated to use Android 12’s new Splashscreen API (see: https://developer.android.com/guide/topics/ui/splash-screen/migrate). It appears that the second of the two fallbacks is being invoked, as expo-splash-screen uses an Activity-based splash screen (per the link above):

If your existing splash screen is implemented using a dedicated Activity, launching your app on devices running Android 12 or higher results in duplicate splash screens: the new system splash screen displays, followed by your existing splash screen activity.

Created a video showing our bare app loading on a Pixel 4a running Android 12 and then a test managed app that I built with the default splash screen doing the same thing. You’ll see exactly the fallback as Google describes it, with the app icon being shown and then transitioning to the actual splash screen.

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

bare

What platform(s) does this occur on?

Android

SDK Version (managed workflow only)

44

Environment

Expo CLI 5.0.3 environment info: System: OS: macOS 11.5.2 Shell: 5.8 - /bin/zsh Binaries: Node: 16.13.2 - /var/folders/xz/f7gw6gb509n2whbvh19b8mrh0000gn/T/yarn–1643228715836-0.6327139417443315/node Yarn: 1.22.4 - /var/folders/xz/f7gw6gb509n2whbvh19b8mrh0000gn/T/yarn–1643228715836-0.6327139417443315/yarn npm: 8.1.2 - ~/.nvm/versions/node/v16.13.2/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.0 - /Users/keith/.rbenv/shims/pod SDKs: iOS SDK: Platforms: DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0 Android SDK: API Levels: 28 Build Tools: 28.0.3 IDEs: Android Studio: 4.1 AI-201.8743.12.41.6953283 Xcode: 13.1/13A1030d - /usr/bin/xcodebuild npmPackages: @expo/webpack-config: ^0.15.0 => 0.15.0 babel-preset-expo: ^8.4.1 => 8.4.1 expo: ^44.0.0 => 44.0.5 react: 17.0.1 => 17.0.1 react-dom: 17.0.1 => 17.0.1 react-native: 0.64.3 => 0.64.3 react-native-web: 0.17.1 => 0.17.1 react-navigation: ^4.3.7 => 4.4.3 Expo Workflow: bare

Reproducible demo

  1. expo init a “minimal” app
  2. expo build:android (or eject and build bare, doesn’t seem to matter)
  3. Run it on Android 12 (confirmed on Pixel 4a)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 8
  • Comments: 24 (5 by maintainers)

Most upvoted comments

This issue is still happening 😞. @byCedric @brentvatne can we reopen this issue, please?

This problem is due to default splash screen in Android 12 To to resolve it you can only replace the default splash screen with a transparent screen Go to res/values/styles.xml and edit the file like this

` <style name="Theme.App.SplashScreen" parent="AppTheme">

<item name="android:windowBackground">@drawable/splashscreen</item>

<item name="android:windowIsTranslucent">true</item> // add this line

</style>`

If that’s what does the trick, this may be the right config plugin to accomplish it in the managed workflow:

const {
  AndroidConfig,
  withAndroidStyles,
} = require("@expo/config-plugins");

const withSplashWindowIsTranslucent = (config) => {
  return withAndroidStyles(config, async (config) => {
    config.modResults = await configureFullScreenDialog(config.modResults);
    return config;
  });
};

async function configureFullScreenDialog(
  styles
) {
  const splashScreen = styles.resources.style.find(
    style => style.$.name === "Theme.App.SplashScreen"
  );

  if (splashScreen) {
    splashScreen.item = splashScreen.item.filter(item => item.$.name !== "android:windowIsTranslucent");
    splashScreen.item.push(
      AndroidConfig.Resources.buildResourceItem({
        name: 'android:windowIsTranslucent',
        value: true
      })
    );
  }

  return styles;
}

module.exports = withSplashWindowIsTranslucent;

I’ll reiterate that this doesn’t seem like something that should be in userland, but rather part of the default splash screen configuration.

Still an issue.

I’m still facing the same issue even when I already added

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

Any solutions please. Thanks

It seems that this inconsistency in user experience for Android 12+ should either be addressed by the implementation of Expo splash config or documentation should be added that warns about the inconsistency. It’s jarring for the user to be presented with multiple branded splash screens.

In response to the suggestion of “creating a splashscreen that closely matches your adaptive icon”, I would note that the uncanniness of the experience goes up the closer the two branded screens are to matching: a big jump in appearance is distracting, but a subtle jump in appearance is unsettling.

don’t use react-native-bootsplash if you are using expo-updates. You will have a white splash after your splash screen. https://github.com/expo/expo/issues/16748

I was able to get it working with this in case @AliMohammad93’s comment wasn’t clear.

image