14

I am trying to create an AAR file for a library Android project using Android Studio and gradle.

I want to exclude from this archive specific folders and files but I cannot find a working solution.

The project has 2 flavours.

app/
|--libs/
|--src/
   |--flavour1/
   |  |--java/
   |     |--a1/
   |     |  |--class_File1.java
   |--flavour2/
   |  |--java/
   |     |--a1/
   |     |  |--class_File1.java
   |--main/
      |--java/
      |  |--...
      |--res/
      |  |--raw/
      |  |  |--comments.txt
      |  |--...
      |--AndroidManifest.xml

and I use a build.gradle file like this one

apply plugin: 'com.android.library'

android {
compileSdkVersion 21
buildToolsVersion "21.1.2"

defaultConfig {
    minSdkVersion 10
    targetSdkVersion 21
}
packagingOptions {
    exclude 'assets'
    exclude '**/comments.txt'
}


sourceSets {

        flavour1 {
            resources {
                exclude '**/comments.txt'
            }
        }
        flavour2 {

        }

}

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
    }
}

productFlavors {

    flavour1 {

       packagingOptions {
            exclude 'assets'
            exclude 'res/raw/comments.txt'
        }
    }
    flavour2 {
    }
}
}

dependencies {
compile 'com.google.android.gms:play-services:+'
}

Generally speaking, I have experimented a lot. I have tried packagingOptions, exclusion in sourceSets but nothing seems to work. What I am trying to achieve is not include for example in the .AAR archive the file comments.txt and the folder "assets" which is an optional folder. I examine each time the .AAR file by renaming it to zip and looking into the files included.

I have also looked into the documentation here, where maybe configurations could be a solution but I am not sure how to use it or how to move forward. Any help will be appreciated.

andreasv
  • 689
  • 3
  • 11
  • 26

2 Answers2

4

Think it is related to this issue. Generally you could try with:

  • Source set excludes
  • Packaging options
  • Aapt options

I couldn't get either of them to work though.

That said, you could make some ugly hacks like this:

def filterVariant = { variantToFilter, filterTask->
        def vv = android.sourceSets."${variantToFilter}".res.srcDirs
        println "${variantToFilter} --> ${vv*.toString()}"

        def variantRes = android.sourceSets."${variantToFilter}".res
        variantRes.srcDirs.each{ resDir->
            def filterOutput = "${buildDir}/res-filter"
            if (resDir.toString().contains(filterOutput)) {
                return
            }

            println "begin filter ${resDir} to ${filterOutput}/${variantToFilter}"

            filterTask.from fileTree(dir: resDir, exclude: '**/comment.txt')
            filterTask.into "${filterOutput}/${variantToFilter}"


            variantRes.srcDirs = ["${filterOutput}/${variantToFilter}"]
        }
    }

    project.task('filterMainResources', type: Copy) {
        filterVariant 'main', it
    }

    android.libraryVariants.all{ variant ->
        project.task("filter${variant.name}Resources", type: Copy) { filterTask ->
            filterVariant "${variant.name}", filterTask
            filterTask.dependsOn "filterMainResources"
        }
        variant.mergeResources.dependsOn("filter${variant.name}Resources")
    }
Samuil Yanovski
  • 2,837
  • 17
  • 19
  • Hello Samuil, thank you for your response. This solution worked. I only had to change the line: filterTask.from fileTree(dir: resDir, exclude: 'raw/comments.txt') to specify that file was in raw folder since ** did not work. thanks! – andreasv Apr 24 '15 at 09:20
0

I can't try it right now, but this would probably be my approach:

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        aidl.srcDirs = ['src']
        resources.srcDirs = ['src']           
        renderscript.srcDirs = ['src']
        java.srcDirs = ['src']
        res.srcDirs = ['res']
    }

    flavor1 {
        java.srcDirs = ['src/main/java', 'src/flavor1/java']         
        res.srcDirs = ['src/flavor1/res'] //this differs from your structure
        assets.srcDirs = []
    }

    flavor2 {
        java.srcDirs = ['src/main/java', 'src/flavor2/java']
        res.srcDirs = ['src/flavor2/res'] //this differs from your structure
        assets.srcDirs = ['src/main/res/raw']
    }
}

Again, I couldn't try it, so this could be complete nonsense. The idea was to not exclude stuff, but only include the files/dirs you do want in you flavor. This may will lead to duplication of files/folders per flavor!

As sources I would recommend: Gralde Plugin User Guide, the answer from Xavier Ducrohet and also this Gradle + Android, want to overwrite /assets with custom folder in buildFlavor.

Community
  • 1
  • 1
sschrass
  • 7,014
  • 6
  • 43
  • 62
  • Hello SateliteSD, thank you for your answer but I am not sure how it answers the question. For example in the code you provided how do i keep the res/raw folder but exclude a specific file from it, for example comments.txt as stated in the question? From my understanding you are just specifying where to look for src, assets and res in the different flavours, nothing more which is not actually the issue here since with the structure of the project flavours look to the right folders during build time. – andreasv Apr 24 '15 at 08:12