Gradle: resources merging with overriding instead of replacing

3,892 views
Skip to first unread message

Anton Rutkevich

unread,
Dec 12, 2013, 9:28:18 AM12/12/13
to adt...@googlegroups.com
Hi everyone, 

is it possible to merge resources with overriding?
Given:

Main source set:
styles.xml
...
<style name="button_text_style">
        <item name="android:textSize">@dimen/btn_txt_size</item>
        <item name="android:textColor">@color/btn_txt_color</item>
        <item name="android:textStyle">bold</item>
</style>

Some flavor's source set:
styles.xml
...
<style name="button_text_style">
        <item name="android:textStyle">italic</item>
</style>
.

Is it possible to obtain 

styles.xml
...
<style name="button_text_style">
        <item name="android:textSize">@dimen/btn_txt_size</item>
        <item name="android:textColor">@color/btn_txt_color</item>
        <item name="android:textStyle">italic</item>
</style>

?

The actual result I have is
styles.xml
...
<style name="button_text_style">
        <item name="android:textStyle">italic</item>
</style>

Xavier Ducrohet

unread,
Dec 12, 2013, 11:45:07 AM12/12/13
to adt...@googlegroups.com
No it's not possible to do exactly that.

However I think you could create a base style, that contains the default values, then in the main source set, you have a style extending it (but likely doing nothing). In the flavor you can then extend it and override what you need.

This would have to be tested though, but I think this could work.


--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Xavier Ducrohet
Android SDK Tech Lead
Google Inc.
http://developer.android.com | http://tools.android.com

Please do not send me questions directly. Thanks!

Anton Rutkevich

unread,
Dec 12, 2013, 1:08:28 PM12/12/13
to adt...@googlegroups.com
Thanks for response, Xavier!

This option sounds good to me. I'll try to implement it.

Anton Rutkevich

unread,
Dec 23, 2013, 1:55:30 PM12/23/13
to adt...@googlegroups.com
So, I have implemented the option. 

At first glance everything seems ok. 

Main source set:
styles.xml
...
<style name="button_text_style" parent="button_text_style_base"/>
<style name="button_text_style_base" >

        <item name="android:textSize">@dimen/btn_txt_size</item>
        <item name="android:textColor">@color/btn_txt_color</item>
        <item name="android:textStyle">bold</item>
</style>

Some flavor's source set:
styles.xml
...
<style name="button_text_style" parent="button_text_style_base">

        <item name="android:textStyle">italic</item>
</style>
.

So, I obtain 

styles.xml
...
<style name="button_text_style" parent="button_text_style_base">

        <item name="android:textStyle">italic</item>
</style>
<style name="button_text_style_base">

        <item name="android:textSize">@dimen/btn_txt_size</item>
        <item name="android:textColor">@color/btn_txt_color</item>
        <item name="android:textStyle">bold</item>
</style>

which is equivalent to 
...
<style name="button_text_style">
        <item name="android:textSize">@dimen/btn_txt_size</item>
        <item name="android:textColor">@color/btn_txt_color</item>
        <item name="android:textStyle">italic</item>
</style>
...
.
That's what I need.


BUT!

When I try to build it, I get the error saying that resources from ActionBarSherlock's could not be found (error message attached).
The error occurs after several clean launches with new styles (maybe some gradle cache problems?).
After error occurs, there are two ways to fix it:
  1. revert styles to the old way they were dfeclared (without '_base' styles) 
  2. add 'res' folders of all AARs to the main source set like this:
    
    android {
        ...
        // Add resources of all aar dependencies to the main sourceSet to workaround bug where aar resources could not be found
        project.configurations.compile.allDependencies.each { dep ->
            if (project.configurations.compile.findAll { it.path.contains(dep.name) && it.path.contains('.aar')}.size() > 0) {
                def groupName = dep.group.split('\\.').collect { it.capitalize() }.join()
                def artifactName = dep.name.capitalize()
                def versionName = dep.version.replace('.', '').replace('-', '')
                def dependencyResourcesPath = "$buildDir/exploded-bundles/${groupName}${artifactName}${versionName}.aar/res"
                // Fix for bug where resources for aar could not be found
                android.sourceSets {
                    main.res.srcDir "$dependencyResourcesPath"
                }
            }
        }
        ...
    }

I'm using the second solution, but it looks like a terrible hack. 

Is this a known problem?
resources_bug.txt

Anton Rutkevich

unread,
Jan 5, 2014, 6:15:36 AM1/5/14
to adt...@googlegroups.com
Android plugin v0.7.3, build tools v19.0.1.
Still can reproduce the problem:
1) delete all 'build' folders
2) ./gradlew clean assembleDebug
3) problem appears

After first run ../build/res/release/values/values.xml contains entries from project only. There are no entries from aar dependencies in it.

Second run of the same ./gradlew command completes successfully.
MergeResources task is not up to date on second run:

:my-lib:mergeReleaseResources
Executing task ':my-lib:mergeReleaseResources' (up-to-date check took 0.076 secs) due to:
    Input file /Users/me/sources/myproject/my-lib/build/exploded-bundles/ComActionbarsherlockActionbarsherlock440.aar/res/drawable-hdpi/abs__btn_cab_done_focused_holo_light.9.png has been added.
    Input file /Users/me/sources/myproject/my-lib/build/exploded-bundles/ComActionbarsherlockActionbarsherlock440.aar/res/layout/abs__activity_chooser_view.xml has been added.
    Input file /Users/me/sources/myproject/my-lib/build/exploded-bundles/ComActionbarsherlockActionbarsherlock440.aar/res/layout/sherlock_spinner_item.xml has been added.
Changed Resource sets: full task run!

Anton Rutkevich

unread,
Jan 30, 2014, 4:08:36 AM1/30/14
to adt...@googlegroups.com
gradle-android-plugin v0.8.0, problem is still here ..

The problem is that with the current ugly fix of the bug I cannot override aar's resources, as they are at the same level as the my-lib's resources ( 

Joe Kueser

unread,
Feb 25, 2014, 5:28:02 PM2/25/14
to adt...@googlegroups.com
Anton,

Were you ever able to find a workaround for this? I'm having a similar problem. In my case the colors.xml file in main is always being used, while the one in my flavor is never being used. Kind of a bummer. Any work-around I can come up with is going to be a lot of work.

Thanks.

Joe

Anton Rutkevich

unread,
Feb 26, 2014, 6:22:16 AM2/26/14
to adt...@googlegroups.com
Joe, 

the only workaround I found is the one I described in this thread earlier. 

The bug can still be reproduced with gradle-android-plugin v0.8.3, and 19.0.1 build tools.
Reply all
Reply to author
Forward
0 new messages