Gradle swap jniLibs resources based on build flavor

后端 未结 3 876
挽巷
挽巷 2021-01-13 10:15

I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a

相关标签:
3条回答
  • 2021-01-13 11:00

    To use flavors to vary source sets,

    productFlavors{
        phone{
        }
        tablet{
        }
    }
    

    Now structure your code like,

    src
      main
      phone
      tablet
    

    The code in main is common between both flavors, but the code in phone or tablet is only included when the respective flavor is built. That's it, you don't need to do anything else.

    The structure under phone and tablet is the same as under main (res, java, etc). You can also have a custom AndroidManifest.xml under the flavor directory. Gradle attempts to merge the flavor's AndroidManifest.xml with the one in main. In some cases you have to provide rules for how to merge.

    0 讨论(0)
  • 2021-01-13 11:07

    some of them mention that you just need separate folders based on build variant and some mention about having to use sourceSet?

    Gradle/Gradle for Android has an expected structure for a sourceset:

    • Android resources in res/
    • Java source tree in java/
    • Pre-compiled JNI libraries in jniLibs/
    • Assets in assets/
    • Etc.

    Where the sourceSets closure comes into play is if, for a given sourceset, you want a different structure:

    • Android resources in foo/
    • Java source tree in bar/
    • Pre-compiled JNI libraries in ickyNativeStuff/
    • Assets in assetsBecauseThatSeemsLikeADecentName/
    • Etc.

    Each build type, product flavor, and build variant can have a separate sourceset (as can androidTest for instrumentation testing), to go along with main. They are named the same as the build type/product flavor/build variant. These will be in the stock structure, unless you use sourceSets to change things.

    So, to roll all the way back to:

    I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a debug buildType

    In the case of resources, other sourcesets overlay main. So, if you have src/main/res/... and src/main/debug/... and src/main/release/..., and you are doing a debug build, whatever is in src/main/release/... is ignored (as we aren't doing release) and whatever is in src/main/res/... and src/main/debug/... will be used. If there is the same resource in both (src/main/res/raw/boom.ogg and src/debug/res/raw/boom.ogg), the debug one trumps the main one.

    I have not experimented with varying jniLibs/ by build variant. My guess is that it will behave more like Java code, where you cannot have conflicts between what is in a build variant's sourceset and what is in main, but that's just a guess. So, you can have the debug version of your compiled JNI code in src/debug/jniLibs/ and the release version of your compiled JNI code in src/release/jniLibs/. Only have in src/main/jniLibs/ any libraries that are not varying. That being said, as I mentioned, I haven't tried this, and so there may be hiccups here.

    So, I would expect you to not have a sourcesets closure in build.gradle, and to just use the stock sourcesets structure, for your various bits:

    src/
      main/
        ...
      debug/
        jniLibs/
        res/
          raw/
      release
        jniLibs/
        res/
          raw/
    
    0 讨论(0)
  • 2021-01-13 11:17

    Anything that's normally under src/main/ can be put in a different folder:

    src/<element>/AndroidManifest.xml
    src/<element>/java
    src/<element>/res
    src/<element>/assets
    src/<element>/resources
    src/<element>/jni
    src/<element>/jniLibs
    src/<element>/aidl
    src/<element>/rs
    

    Where element is the name of a build type or a product flavor. If your variant includes such a element (build type or flavor), then that source set is also used in addition to src/main

    Note that the location is really not relevant if you have configured it. What matters is that there is a android.sourcesets.main element that contains the sources common to all variants, and each variant has a set of sourcesets.

    For instance if you have a flavor phoneRelease it's really using the following sourcesets:

    android.sourcesets.main
    android.sourcesets.phone
    android.sourcesets.release
    android.sourcesets.phoneRelease
    

    If you have another variant tabletRelease, it'll use the following:

    android.sourcesets.main
    android.sourcesets.tablet
    android.sourcesets.release
    android.sourcesets.phoneRelease
    

    So the phone/tablet sourceset is different and is where you'd put the variant specific sources, unless you want to be even more specific and use the phoneRelease/tabletRelease sourcesets (though those are less used generally.) By default these would be src/phone/... and src/tablet/... (or src/phoneRelease/...) but you can change that however you want and as long as it's connected to the android.sourcesets.* objects it'll be fine.

    for example, doing:

    android {
      sourcesets {
        phone {
          jniLibs.srcDirs = ['phoneRelease/jniLibs/']
        }
        tablet {
          jniLibs.srcDirs = ['tabletRelease/jniLibs/']
        }
      }
    }
    

    is fine. But do be aware that you only changed the jniLibs folder and not the other source elements (java, res, etc...)

    If you kept the default location for the main sourcesets, I'd just keep everything under src/

    You can see more info about sourcesets and how multiple sourcesets are combined here: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies

    0 讨论(0)
提交回复
热议问题