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

Android Manifest uses the wrong style resource id when building a universal apk with dynamic features #68

Closed
jamieadkins95 opened this issue Apr 18, 2019 · 13 comments

Comments

@jamieadkins95
Copy link

Describe the bug

We have adopted dynamic features in our project, and these dynamic features have their own themes defined. Since the base module needs to know about these styles to do a manifest merge, we include some stub styles in the base module:

base/src/main/res/styles.xml

<resources>
    <style name="OnboardingTheme" />
    ...
</resources>

The onboarding module actually defines this theme:

onboarding/src/main/res/styles.xml

<resources>
    <style name="OnboardingTheme" parent="Theme.MaterialComponents">
        <item name="colorPrimary">@color/primary</item>
        ...
    </style>
</resources>

The AndroidManifest in onboarding looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.example">

    <dist:module
        dist:instant="false"
        dist:onDemand="false">
        <dist:fusing dist:include="true" />
    </dist:module>

    <application>
        <activity
            android:name=".OnboardingActivity"
            android:screenOrientation="portrait"
            android:theme="@style/OnboardingTheme" />
    </application>

</manifest>

When I build the bundle and then deploy the bundle to my device using --connected-device, everything works as expected. Onboarding uses the correct theme with all the colors and everything.

However, when I build a universal apk using --mode=universal, the tools successfully builds an apk, but when I install it on a device I get a crash when onboarding is launched:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity

When I inspect the universal.apk and the resources.arsc, I can see that the Manifest is pointing to the stub style in base and not the style defined in onboarding.

If I move the theme to base, then everything works again. But this is obviously not ideal.

Is this a bug, or an oddity with the way universal apks are built that I don't understand?

Any advice would be super appreciated.

Bundletool version(s) affected
Version: 0.9.0

To Reproduce

  • In a project with dynamic features, add custom styles
  • Build a bundle using ./gradlew base:bundleDebug
  • Build a universal apk bundletool build-apks --bundle=base/build/outputs/bundle/debug/base.aab --mode=universal --output="app.apks" --overwrite
  • Install the APK unzip app.apks and adb install universal.apk
  • Observe crash when the Activity with that style is launched.

Expected behavior
No crash and correct styles to be used

Known workaround
Move all styles to the base module

@kvafy
Copy link
Collaborator

kvafy commented Apr 23, 2019

In bundletool, the universal APK at the moment simply adopts AndroidManifest.xml from the base module (here) and it is assumed that all necessary merging of the manifests has been performed by Gradle when building the bundle. If curious, command bundletool dump ... can be used to inspect the raw manifests and resource tables inside a bundle.

I'll follow-up with more details after closer investigation. Thank you for thorough report!

@jamieadkins95
Copy link
Author

Thanks @kvafy, I can provide a bundle from our project if you would like something to play around with?

Would need to share it in private, but just let me know where to send it and I'll send it over

@kvafy
Copy link
Collaborator

kvafy commented Apr 24, 2019

That would useful. Please share the bundle by contacting the Play Console support team ("Contact us > Send feedback & report bugs"). Internally they can route the support case to me by name (not by GitHub handle).

@jamieadkins95
Copy link
Author

I have passed the bundle on to the support team :)

@jamieadkins95
Copy link
Author

@kvafy have you received the bundle?

We are now shipping to the Play Store using app bundles in our project, however we are blocked from shipping with dynamic features since our min SDK is 16. Since there is no split apk support that low, the apk generated by bundletool for those devices suffer the same problem as the universal apk, where the wrong style definition is used.

@plecesne
Copy link
Contributor

plecesne commented Jun 1, 2019

Yes, we have received it but haven't had time to have a closer look yet.

You mentioned a workaround of putting the style in the base. Does that increase the size of your APK by much? I know this isn't ideal, but that may unblock you from shipping dynamic features at possibly little cost until we have a better understanding of whether this can be fixed.

@plecesne
Copy link
Contributor

plecesne commented Jun 1, 2019

I had a quick look.

Do you define the OnboardingActivity in the base manifest as well, or only in the onboarding module?

The Android Gradle plugin merges all of the manifests in the base module, but I see that the referenced style for the OnboardingActivity is different in the base module and in the onboarding module.

As mentioned by kavfy, today, bundletool does not touch the manifests when generating the universal and standalone APKs. I can see how this would be useful for your use-case though to override the activity definitions when there is a conflict. More investigation is going to be needed unfortunately to make sure this is the right way to do it and that this doesn't have any negative impact on other existing apps.

@jamieadkins95
Copy link
Author

I know this isn't ideal, but that may unblock you from shipping dynamic features at possibly little cost until we have a better understanding of whether this can be fixed.

Yeah, we'll probably end up doing this in the mean time.

Do you define the OnboardingActivity in the base manifest as well, or only in the onboarding module?

It's only defined in the onboarding module. Should I try defining it in the base manifest as well?

More investigation is going to be needed unfortunately to make sure this is the right way to do it and that this doesn't have any negative impact on other existing apps.

Appreciate that, let me know if there is anything else I can provide to help.

@tinsukE
Copy link

tinsukE commented Dec 6, 2019

+1
This issue becomes specially painful if you're using Firebase App Distribution or Test Labs, since both services require a universal APK (Test Labs supports upload of AAB files, but it doesn't seem to support dynamic feature modules, since only the base APK gets installed).

@ymakhno
Copy link

ymakhno commented Mar 27, 2020

Fixed in 0.13.4.

@ymakhno ymakhno closed this as completed Mar 27, 2020
@jamieadkins95
Copy link
Author

@ymakhno Amazing! Thanks for fixing this!

I have a couple more questions:

  • I'm struggling to get this to work locally, I still end up with the wrong style in universal apk builds. Is there a flag I need to enable or something?
  • This fix helps us clear up a load of mess with our styles by allowing us to move them out of base. However merging those changes and releasing an update requires the Play Store to be using bundletool 0.13.4, otherwise users installing on devices running SDK < 21 are still going to see crashes. Do you know when the Play Store will adopt 0.13.4?

@ymakhno
Copy link

ymakhno commented Mar 30, 2020

@jamieadkins95 please find the answer below:

  • to enable it your bundle should be built using new version of bundletool 0.13.4. If you have problem I assume you are building aab file using gradle plugin. In this case try to add new version of bundletool to your buildscript dependencies:
buildscript {
    repositories {
        google()
        jcenter()
        ...
    }
    dependencies {
        classpath "com.android.tools.build:bundletool:0.13.4"
        ...
    }
    ...
}
  • I think this fix should be available in Play Store by the end of this week but it may take couple of weeks. Will let you know once it is there.

@jamieadkins95
Copy link
Author

Oh interesting, I didn't realise bundletool was actually involved internally in the AGP, thought I could just build the universal apk using 0.13.4 on the command line. Adding the dependency to the build.gradle worked, thanks for the info!

@google google deleted a comment from erprad8 Jun 1, 2020
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

5 participants