Gradle交换jniLibs资源基于构建风格

时间:2015-07-28 21:35:49

标签: android gradle android-gradle

我正在尝试根据res/rawjniLibs/armeabi来替换release buildType文件夹和debug buildType文件夹中的某些资源。我目前也有两种产品口味。

build.gradle文件:

apply plugin: 'com.android.application'

android {
    dexOptions {
        preDexLibraries = false
    }

    compileSdkVersion 21
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.example.test"
        minSdkVersion 17
        targetSdkVersion 22
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7
        }
    }

    productFlavors{
        phone{
            applicationId "com.example.testPhone"
        }
        tablet{
            applicationId "com.example.testTablet"
        }
    }

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

    sourceSets{
        release{
            res.srcDirs = ['androidRelease/res/raw']
        }
    }
}

dependencies {
    compile project(':facebook')

}

正确使用sourceSet这样做吗?如果是,应创建哪个文件夹,以便仅根据buildType交换适当的资源,而不管productFlavors

编辑:是否可以交换jniLibsraw文件夹资源?

文件夹结构:

src/main/jniLibs/armeabi
phoneRelease/jniLibs/armeabi
tabletRelease/jniLibs/armeabi 

文件夹结构是否正确。?

编辑2: 基于Xavier的回答,这个gradle应该是这样的:

android {

      sourcesets {
        phone {
          jniLibs.srcDirs = ['phoneRelease/jniLibs/']
          res.srcDirs = ['androidRelease/res/raw']
        }
        tablet {
          jniLibs.srcDirs = ['tabletRelease/jniLibs/']
          res.srcDirs = ['androidRelease/res/raw']
        }
      }
    }

我一直在阅读许多相互矛盾的答案,其中一些人提到你只需要基于构建变体的单独文件夹,并且有些人提到必须使用sourceSet? 谢谢!

3 个答案:

答案 0 :(得分:4)

通常在src/main/下的任何内容都可以放在不同的文件夹中:

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

其中elementbuild typeproduct flavor的名称。如果您的变体包含这样的元素(构建类型或风格),那么该源集也使用另外src/main

请注意,如果您已配置位置,则该位置确实无关紧要。 重要的是有一个android.sourcesets.main元素包含所有变体共有的源,每个变体都有一组源集。

例如,如果您有一种风味phoneRelease,它确实使用以下源集:

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

如果您有其他变体tabletRelease,则会使用以下内容:

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

因此,phone / tablet源集不同,您可以将变体特定来源放在哪里,除非您想要更具体并使用phoneRelease / tabletRelease源集(尽管通常较少使用它们。)默认情况下,它们可以是src/phone/...src/tablet/...(或src/phoneRelease/...),但您可以根据需要随时更改因为它与android.sourcesets.*对象相关联,所以它会很好。

例如,做:

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

很好。但请注意,您只更改了jniLibs文件夹而不更改其他源元素(java,res等等)

如果您保留main来源集的默认位置,我只需将所有内容保留在src/

您可以在此处查看有关源集以及如何组合多个源集的更多信息:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies

答案 1 :(得分:4)

  

其中一些人提到你只需要基于构建变体的单独文件夹,并且有些人提到必须使用sourceSet?

Android的Gradle / Gradle具有源集的预期结构:

  • res/
  • 中的Android资源
  • java/
  • 中的Java源代码树
  • jniLibs/
  • 中预编译的JNI库
  • assets/
  • 中的资产

sourceSets闭包发挥作用的情况下,对于给定的源集,您是否需要不同的结构

  • foo/
  • 中的Android资源
  • bar/
  • 中的Java源代码树
  • ickyNativeStuff/
  • 中预编译的JNI库
  • assetsBecauseThatSeemsLikeADecentName/
  • 中的资产

每个构建类型,产品风格和构建变体都可以有一个单独的源集(对于检测测试可以androidTest),与main一起使用。它们的名称与构建类型/产品flavor / build变体的名称相同。这些将在股票结构中,除非您使用sourceSets来改变事物。

所以,一直回到:

  

我正在尝试根据res / raw文件夹和调试buildType

来交换res / raw文件夹和jniLibs / armeabi文件夹中的一些资源。

对于资源,其他源集重叠main。因此,如果您有src/main/res/...src/main/debug/...以及src/main/release/...,并且您正在进行debug构建,src/main/release/...中的任何内容都会被忽略(因为我们不是'执行release)以及src/main/res/...src/main/debug/...中的任何内容都将被使用。如果两者中都有相同的资源(src/main/res/raw/boom.oggsrc/debug/res/raw/boom.ogg),则debug胜出main一个。

我没有通过构建变体尝试变更jniLibs/。我的猜测是它的行为更像Java代码,你不能在构建变量的sourceset和main中的内容之间产生冲突,但这只是猜测。因此,您可以在src/debug/jniLibs/中编译已编译的JNI代码的调试版本,并在src/release/jniLibs/中编译已编译的JNI代码的发行版本。只有src/main/jniLibs/中没有变化的库。话虽如此,正如我所说,我没有尝试过,所以这里可能会出现打嗝。

所以,我希望你在sourcesets中没有build.gradle闭包,并且只使用股票源集结构,为你的各个位:

src/
  main/
    ...
  debug/
    jniLibs/
    res/
      raw/
  release
    jniLibs/
    res/
      raw/

答案 2 :(得分:0)

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.