zoontek / react-native-bootsplash

🚀 Show a splash screen during app startup. Hide it when you are ready.
MIT License
3.75k stars 259 forks source link

Android crashes on setOnExitAnimationListener #394

Closed egealpay closed 2 years ago

egealpay commented 2 years ago

Bug summary

Hi,

According to Firebase logs, my app is crashing when setOnExitAnimationListener called, on OPPO and RealMe devices with Android 9 and 10. I have tried on Samsung, Huawei, Lenovo and Xiaomi but could not generate the bug.

Here is the logs of the crash:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ea.app/com.ea.app.MainActivity}: android.view.InflateException: Binary XML file line #24 in com.ea.app:layout/splash_screen_view: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f030240 a=-1}
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3532)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3687)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2230)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:237)
       at android.app.ActivityThread.main(ActivityThread.java:7817)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1027)

More detailed logs:

Caused by java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f030240 a=-1}
       at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:825)
       at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:8135)
       at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:8333)
       at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:452)
       at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:380)
       at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:58)
       at android.view.LayoutInflater.rInflate(LayoutInflater.java:1144)
       at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1103)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
       at android.view.View.inflate(View.java:26282)
       at androidx.core.splashscreen.SplashScreenViewProvider$ViewImpl$_splashScreenView$2.invoke(SplashScreenViewProvider.kt:94)
       at androidx.core.splashscreen.SplashScreenViewProvider$ViewImpl$_splashScreenView$2.invoke(SplashScreenViewProvider.kt:93)
       at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
       at androidx.core.splashscreen.SplashScreenViewProvider$ViewImpl.get_splashScreenView(SplashScreenViewProvider.kt:93)
       at androidx.core.splashscreen.SplashScreenViewProvider$ViewImpl.createSplashScreenView(SplashScreenViewProvider.kt:103)
       at androidx.core.splashscreen.SplashScreenViewProvider.<init>(SplashScreenViewProvider.kt:52)
       at androidx.core.splashscreen.SplashScreen$Impl.setOnExitAnimationListener(SplashScreen.kt:305)
       at androidx.core.splashscreen.SplashScreen.setOnExitAnimationListener(SplashScreen.kt:185)
       at com.zoontek.rnbootsplash.RNBootSplashModule.init(RNBootSplashModule.java:75)
       at com.zoontek.rnbootsplash.RNBootSplash.init(RNBootSplash.java:10)
       at com.ea.app.MainActivity.onCreate(MainActivity.java:65)
       at android.app.Activity.performCreate(Activity.java:7980)
       at android.app.Activity.performCreate(Activity.java:7969)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3503)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3687)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2230)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:237)
       at android.app.ActivityThread.main(ActivityThread.java:7817)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1027)

I don't have a file called as splash_screen_view. I have checked some files in androidx.core:core-splashscreen and saw the following code in SplashScreenViewProvider.kt file:

private val _splashScreenView: ViewGroup by lazy {
            FrameLayout.inflate(
                activity,
                R.layout.splash_screen_view,
                null
            ) as ViewGroup
        }

This code is trying to access splash_screen_view and I believe that is it reason of the crash.

Library version

4.3.2

Environment info

System:
    OS: macOS 12.6
    CPU: (8) x64 Apple M1
    Memory: 21.93 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.19.3 - ~/.nvm/versions/node/v14.19.3/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v14.19.3/bin/yarn
    npm: 8.12.1 - ~/.nvm/versions/node/v14.19.3/bin/npm
    Watchman: 2022.08.29.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0
    Android SDK:
      API Levels: 26, 28, 29, 30, 31, 33
      Build Tools: 27.0.3, 28.0.3, 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0
      System Images: android-28 | Google APIs ARM 64 v8a, android-30 | Google Play ARM 64 v8a, android-31 | Google APIs ARM 64 v8a, android-31 | Google Play ARM 64 v8a
      Android NDK: Not Found
  IDEs:
    Android Studio: 2021.1 AI-211.7628.21.2111.8139111
    Xcode: 14.0/14A309 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.16 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.1.0 => 18.1.0 
    react-native: 0.70.2 => 0.70.2 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

I could not generate the bug in my test devices, but according to Firebase, app crashes after these steps:

  1. Install the app
  2. See the splash screen
  3. App will crash while hiding the splash screen

Reproducible sample code

-
zoontek commented 2 years ago

@egealpay I don't have such devices to test this. Just in case, can you provide your styles.xml, the content of your res/layout directory?

I recommend checking in the Google issue tracker for similar issues. It looks like a bug in AndroidX core splashscreen module (or in Oppo / Realme android forks), not really related to this library bindings (but it could be nice to solve this in AndroidX tho).

EDIT: The layout is embed in the core module and is not complex. I don't know what this phones do to fuck this up.

egealpay commented 2 years ago

@zoontek Here is the styles.xml file:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>

    + <!-- BootTheme should inherit from Theme.SplashScreen -->
    <style name="BootTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/petrol</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
        <item name="postSplashScreenTheme">@style/AppTheme</item>
    </style>

</resources>

I have single file in res/layout which is unrelated with splash screen.

I will check Google Issue Tracker, as you stated, it is probably related with Oppo and RealMe forks. (Which is out of scope of this library). I will try to find an Oppo devices. If I find any more information, I will let you know.

Thanks

zoontek commented 2 years ago

@egealpay This might sound weird, but as you have an app layout directory, try copy & paste the splash_screen_view.xml file inside it, just in case.

That's not how Android is supposed to works, but hey, these phones don't run "proper" Android versions 😅

egealpay commented 2 years ago

I will try that 😄

glesperance commented 2 years ago

@zoontek @egealpay

I am having this exact bug. I can repro it in Android 11 emulator. Android 12 works fine.

Removing rn-bootsplash fixes the problem for me -- which causes me to think there are weird interactions going on with the RNBootsplash package.

I've tried your suggestion @zoontek of copying & pasting the splash_screen_view.xml file inside my project. Although it doesn't fully fix the issue, removing all children and making layout/splash_screen_view.xml as follows, allows the app to load.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="false"
    android:fitsSystemWindows="false">
</FrameLayout>

This however doesn't allow us to see the bootsplash screen. Only a blank page.

@zoontek could something inside super.onCreate try to execute and access layout/splash_screen_view and prevent bootsplash from working?

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    RNBootSplash.init(this); // <- initialize the splash screen
    super.onCreate(savedInstanceState); // or super.onCreate(null) with react-native-screens
  }
glesperance commented 2 years ago

Update:

The problem was with a renaming of the Theme.SlashScreen properties that we wish to override. [1]

Changing your android/app/src/main/res/values/styles.xml file to:

<resources>

  <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <!-- Your base theme customization -->
  </style>

  <!-- BootTheme should inherit from Theme.SplashScreen -->
  <style name="BootTheme" parent="Theme.SplashScreen">
    <item name="windowSplashScreenBackground">@color/bootsplash_background</item>
    <item name="windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
+   <item name="android:windowSplashScreenBackground">@color/bootsplash_background</item>
+   <item name="android:windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
    <item name="postSplashScreenTheme">@style/AppTheme</item>
  </style>

</resources>

almost fixes the issue -- the splash screen still however doesn't show for a long time and all we see is a blank BG.

[1] https://github.com/androidx/androidx/blob/2605522656c3646507e4668f238da804e57829d6/core/core-splashscreen/src/main/res/values-v31/styles.xml#L19-L20

egealpay commented 2 years ago

@egealpay This might sound weird, but as you have an app layout directory, try copy & paste the splash_screen_view.xml file inside it, just in case.

That's not how Android is supposed to works, but hey, these phones don't run "proper" Android versions 😅

Today I got the OPPO device to produce this bug. As you mentioned, I have created splash_screen_view.xml file and placed a FrameLayout with background color. Bug is gone, however it shows a default white screen for Splash Screen

zoontek commented 2 years ago

@egealpay Just thought about it again, and unfortunately this is not a viable solution. Did you ask on Google issue tracker?

egealpay commented 2 years ago

@zoontek I think I found the issue on Google Issue Tracker: https://issuetracker.google.com/issues/207386164

When I try to open the app from application list, it is crashing. But If I click a dynamic link, it opens the app by showing the splashing screen without any error. Probably phone application launcher causes this error.

Also I have created a new issue: https://issuetracker.google.com/issues/256543973

egealpay commented 2 years ago

@zoontek I have fixed the problem, it was causing because of a very simple mistake that I did in manifest file.

I was trying to set theme both for Application and Activity.

<application
        android:name=".MainApplication"
        ...
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            ...
            android:theme="@style/BootTheme">          
        </activity>
    </application>

I changed it to use BootTheme only in Application and nothing in Activity. Now, Splash screen works on OPPO phones.

zoontek commented 2 years ago

@egealpay Thanks for the feedback! It will help people searching for similar issues 🙂