cordova-android: App crashes on splash screen after upgrading to Cordova 11.0.0 on any API level less than 30. 31 + work.

Bug Report

Problem

After upgrading to Cordova 11.0.0 from 8.0.0, the app is crashing on the splash screen. Before this error I hadn’t changed the config.xml to handle the new splash screen for API level 31 and up. Even without doing anything API levels 31 and up work without crashing and show the icon during the splash.

What is expected to happen?

Launch normally in api level 30 and below after splash, just like api 31 and up.

What does actually happen?

it crashes on this line for splash_screen_view .MainActivity}: android.view.InflateException: Binary XML file line #24 layout/splash_screen_view

Information

I saw this ticket number 1534 that had a similar issue. I tried what was suggested and it didn’t work for me. This ticket also mentioned 1479, I also tied what was mentioned here which didn’t work either.

The following Cordova 11 Doc mentions that the old <splash> tags are to be removed from the config.xml file and replaced with ‘AndroidWindowSplashScreenAnimatedIcon’. I removed all my splash tags and added the new preference. The following is a copy of my Android platform config

<platform name="android">
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
        <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
        <icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
        <icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
        <icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
        <preference name="AndroidWindowSplashScreenAnimatedIcon" value="resources/splash.xml" />
        <preference name="AndroidWindowSplashScreenBackground" value="#6F7378" />
        <custom-config-file parent="/*" target="AndroidManifest.xml">
            <application android:allowBackup="false" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
                <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:exported="true" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@style/Theme.AppCompat.NoActionBar" android:windowSoftInputMode="adjustResize">
                    <intent-filter android:label="@string/launcher_name">
                        <action android:name="android.intent.action.MAIN" />
                        <category android:name="android.intent.category.LAUNCHER" />
                    </intent-filter>
                </activity>
                <meta-data android:name="io.fabric.ApiKey" android:value="xxxxxxx" />
            </application>
        </custom-config-file>
    </platform>

I crated the xml file by converting a png to an svg and then using the svg in the Android Asset studio for Images to create the xml. I used a new temp project to do this and copied just the ic_launcher_foreground.xml. Is this wrong way to go about it? The Cordova doc suggests that this is all that is needed for backward compatibility.

Crash Report

D/PluginManager: startupPlugins: put - CoreAndroid D/PluginManager: postMessage: setupSplashScreen D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: com.company.app, PID: 1832 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.app/com.company.app.MainActivity}: android.view.InflateException: Binary XML file line #24 in com.company.app:layout/splash_screen_view: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0300df a=-1} at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: android.view.InflateException: Binary XML file line #24 in com.company.app:layout/splash_screen_view: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0300df a=-1} Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0300df a=-1} at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:826) at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:8231) at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:8429) 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:1123) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) at android.view.LayoutInflater.inflate(LayoutInflater.java:680) at android.view.LayoutInflater.inflate(LayoutInflater.java:532) at android.view.LayoutInflater.inflate(LayoutInflater.java:479) at android.view.View.inflate(View.java:26707) 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 org.apache.cordova.SplashScreenPlugin.setupSplashScreen(SplashScreenPlugin.java:141) at org.apache.cordova.SplashScreenPlugin.onMessage(SplashScreenPlugin.java:113) at org.apache.cordova.PluginManager.lambda$postMessage$0(PluginManager.java:345) at org.apache.cordova.PluginManager$$ExternalSyntheticLambda0.accept(Unknown Source:8) at java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) at java.util.Collections$SynchronizedMap.forEach(Collections.java:2698) at org.apache.cordova.PluginManager.postMessage(PluginManager.java:343) at org.apache.cordova.CordovaActivity.init(CordovaActivity.java:161) at org.apache.cordova.CordovaActivity.loadUrl(CordovaActivity.java:234) at com.company.app.MainActivity.onCreate(MainActivity.java:40) at android.app.Activity.performCreate(Activity.java:8000) E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Command or Code

cordova prepare

grunt init

cordova build android --debug

Environment, Platform, Device

Android API level <= 30

Version information

Mac OS Bug Sur 11.7.1

Android Studio Electric Eel | 2022.1.1

Cordova Android 11.0.0

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 19 (7 by maintainers)

Most upvoted comments

image image image Running successed.

@breautek So I tried both just removing the AppCompat theme from the item in the config file as well as adding it as an AndroidPostSplashScreenTheme in . In both cases I’m getting this error.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company/com.company.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

Could it be something else interfering ? Is your intent filter section different ?

Something else could be interfering. The cordova CLI sets up the native project, and you can view the AndroidManifest at <cordovaProject>/platforms/android/app/src/main/AndroidManifest.xml. It should have android:theme="@style/Theme.App.SplashScreen" on the activity element. If it doesn’t, you’ll have problems.

Although the error seems like it’s actually passing the splashscreen stage is now trying to render the main activity. CordovaActvity extends AppCompatActivity, which is why I think it reqiures a Theme.AppCompat theme (like Theme.AppCompat.NoActionBar)

You can check <cordovaProject/platforms/android/app/src/main/res/values/themes.xml.

It should contain:

<item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item>

Where the assigned theme is controlled by the AndroidPostSplashScreenTheme preference, but it defaults to @style/Theme.AppCompat.NoActionBar. If this is set to a non AppCompat theme, then I expect it’s the source of your current year.

If you have a plugin or something overriding the themes.xml file, it must produce something that has the following:

<?xml version='1.0' encoding='utf-8'?>
<resources>
    <style name="Theme.App.SplashScreen" parent="Theme.SplashScreen.IconBackground">
        <item name="windowSplashScreenBackground">@color/cdv_splashscreen_background</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/ic_cdv_splashscreen</item>
        <item name="windowSplashScreenAnimationDuration">200</item>
        <item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item>
    </style>
</resources>

The postSplashScreenTheme resource is read by Google’s splashscreen library to set the theme of the app activity when the splashscreen is dismissed.

@breautek This worked! I wanted to unit test a bit before I confirmed with you. As you suspected, the theme was the issue. When I got the error stating that I needed a theme that is a descendent of Theme.AppCompat, I set android:theme=@style/Theme.AppCompat.NoActionBar. This got rid of the build error, and when I tested on API level 31 and above it worked properly. I assumed it must be something else causing the older API levels to not work.

The correct value for ‘android:theme’ in my case specifically is ‘@style/Theme.App.SplashScreen’. Setting AndroidPostSplashScreenTheme in config.xml was not necessary in my case like you said since that is already the default. I also tested with the AndroidWindowSplashScreenAnimatedIcon line removed in the config file, and the app just defaulted to the cordova icon, didn’t crash and continued to work.

Thanks again for helping out with this bug.

@breautek

So the AndroidManifest.xml file doesn’t have android:theme at all when I build without it set in the config.xml file. The themes.xml in res/values looks exactly like your copy.

Then something must be overwriting it…

I’m guessing the custom-config-file is overwriting the entire tag.

So perhaps you still need to explicitly configure it when you use the custom-config-file plugin to change the <activity> tag.


<custom-config-file parent="/*" target="AndroidManifest.xml">
            <application android:allowBackup="false" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
                <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:exported="true" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@style/Theme.App.SplashScreen" android:windowSoftInputMode="adjustResize">
                    <intent-filter android:label="@string/launcher_name">
                        <action android:name="android.intent.action.MAIN" />
                        <category android:name="android.intent.category.LAUNCHER" />
                    </intent-filter>
                </activity>
                <meta-data android:name="io.fabric.ApiKey" android:value="xxxxxxx" />
            </application>
        </custom-config-file>

If that works, you may also want to compare against the cordova default AndroidManifest.xml and to see if there is anything else that you’re missing…

ic_launcher_foreground

@breautek I tried just now with this png. I took the largest version of the png I had and used the Android Vector Asset studio you mentioned. In the previous build I had taken the original png, and converted that to an svg and then used the Asset studio to convert the svg to and xml. neither of these approaches worked for me. I should mention, that in both cases, I used the Asset Studio and took the resulting ‘_foreground.’ file and placed in the my resources folder and referenced it in the config as the value for “AndroidWindowSplashScreenAnimatedIcon”.

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.baniyan.travels/com.baniyan.MainActivity}: android.view.InflateException: Binary XML file line #24 in com.baniyan.layout/splash_screen_view: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f030243 a=-1} at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3606) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3778) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:8097) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

Android 13 is working fine but lower android versions like 11, 10, and 9 have this same issue occurred