Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Android Splashscreen theme quirk #1290

Open
breautek opened this issue Mar 14, 2023 · 3 comments
Open

Document Android Splashscreen theme quirk #1290

breautek opened this issue Mar 14, 2023 · 3 comments

Comments

@breautek
Copy link
Contributor

A common issue people are having when upgrading to cordova-android@11 with the new splashscreen system is Google's compatibility library imposes a requirement on the app to use the splashscreen theme as the default starting theme. However many users are using custom configs and/or plugins to override this theme with another which causes the compatibility library to crash with an error message that isn't very useful.

The full stack trace as an example can be found below:

Stacktrace
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: io.cordova.hellocordova, PID: 14640
    java.lang.RuntimeException: Unable to start activity ComponentInfo{io.cordova.hellocordova/io.cordova.hellocordova.MainActivity}: android.view.InflateException: Binary XML file line #24 in io.cordova.hellocordova: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:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        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:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: android.view.InflateException: Binary XML file line #24 in io.cordova.hellocordova: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:825)
        at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:7932)
        at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:8130)
        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:1125)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
        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:25742)
        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 io.cordova.hellocordova.MainActivity.onCreate(MainActivity.java:40)
E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        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:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

This should be documented in some fashion in our Quirks section. I don't think we need ot include the entire stack, but key parts like

Caused by: android.view.InflateException: Binary XML file line #24 in io.cordova.hellocordova: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}

References:
apache/cordova-android#1559
apache/cordova-android#1534
apache/cordova-android#1497

@andreszs
Copy link

andreszs commented Aug 29, 2023

The workaround I found (so far) is to edit AndroidManifest.xml and replace:android:theme="@style/Theme.AppCompat.NoActionBar"
with: android:theme="@style/Theme.App.SplashScreen"

However, everytime the app is built, this change is reverted.

Any ideas on how to workaround this issue? This constant double-building is really tiresome and inconvenient.

@breautek
Copy link
Contributor Author

The workaround I found (so far) is to edit AndroidManifest.xml and replace:android:theme="@style/Theme.AppCompat.NoActionBar" with: android:theme="@style/Theme.App.SplashScreen"

However, everytime the app is built, this change is reverted.

Any ideas on how to workaround this issue? This constant double-building is really tiresome and inconvenient.

You'll have to find what is actually manipulating the theme. Assuming that your project doesn't have a edit-config rule that makes this modification in your config.xml, then there is likely a plugin that is responsible. You can probably do a "find in folder" search on your plugins/ folder to see which plugin.xml has Theme.AppCompat.NoActionBar keyword.

Once you pinpoint the plugin that is overwriting that change, then you'll have to ask the maintainers of the plugin to solve the problem, or fork the plugin and make the change required.

@style/Theme.App.SplashScreen is the value that Cordova itself uses and, and the theme is defined in themes.xml

@andreszs
Copy link

andreszs commented Aug 29, 2023

Thanks Norman, instead of dealing all the plugins I simply added this to my config.xml to have the proper style set automatically on build time:

<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
	<activity android:theme="@style/Theme.App.SplashScreen"></activity>
</edit-config>

For anyone else in search for this solution, this requires the XML namespace xmlns:android="http://schemas.android.com/apk/res/android" in your widget element in config.xml.

Update

My own cordova-plugin-in-app-updates was changing the theme for its own purposes of showing a notification bar. I have updated the plugin to remove that and now everything works without the edit-config option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants