Android build.gradle文件

一、ABI(Application Binary Interface)应用程序二进制接口

     其实ABI可以不设置,这样编译时,就会将项目里所有依赖资源包里的so库都打到最终的apk里。 但是,ABI支持多的话,apk也会大,所以一般只支持一种即可。 目前Android 版本,ABI一般配置armeabi-v7a.

注意:

新增so库

新增so库的话,需要在每个在用的文件夹内(armeabi、armeabi-v7a、arm64-v8a ==)放置,否则so库找不到。多个目录,目录下的so库文件数需要相同。

armeabi-v7a 和 armeabi

如果设置支持armeabi-v7a 和 armeabi:如若第三方提供的so只有armeabi,那么armeabi-v7a 内也需要拷贝一份,原因是armeabi-v7a 和 armeabi必须so数一致,且armeabi-v7a支持armeabi hardware does not support

ABI设置错误,可能出现硬件不支持的问题,提示:hardware does not support

二、splits 的属性

1、abi

  • 类型:AbiSplitOptions
  • 描述:对 abi 进行分包处理,具体我们看下面 AbiSplitOptions 讲解。

2、AbiSplitOptions 类型

2.1 enable

  • 描述:是否开启 abi 分包,默认不开启
  • 使用:

splits {
    abi {
        enable true
    }
}
效果图如下:

Android build.gradle文件_第1张图片

2.2 exclude
描述:排除不需要的架构。
使用:

abi {
    // 是否开启
    enable true

    // 排除不必要的架构
    exclude 'x86','arm64-v8a'
}

效果图:

Android build.gradle文件_第2张图片
2.3 reset
描述:清除默认架构列表。当我们开启abi 分包时,gradle会帮我们初始化一个架构列表,例如 enable 小节中,我们并没有设置任何架构,而gradle会帮我们分出 “arm64-v8a”、“armeabi-v7a”、“x86”、“x86_64”。
初始化列表会因为gradle的版本不同有所改变

使用:

abi {
    // 是否开启
    enable true

    // 重置包含的目录
    reset()
}
2.4 include
描述:设置我们需要的架构。注意的是,我们需要先使用reset方法将默认列表清空,然后再设置。

使用:

abi {
    // 是否开启
    enable true

    // 重置包含的目录,因为已经是包含全部
    reset()
    // 设置包含,调用前需要先用 reset 将默认清除
    include 'armeabi-v7a', 'x86'
}
效果图:

Android build.gradle文件_第3张图片
2.5 universalApk
描述:是否编译一个包含全部架构的apk。
使用:

abi {
    // 是否开启
    enable true

    // 是否打出包含全部的apk
    universalApk true
}
效果图:

Android build.gradle文件_第4张图片

三、sourceSets属性——文件路径配置

 sourceSets {
      main {
           manifest.srcFile 'AndroidManifest.xml' // 指定清单文件
           res.srcDirs = ['res'] // 指定res资源目录
           assets.srcDirs = ['assets']    // asset资源目录
           jni.srcDirs 'src/main/jni'     // jni代码目录
           jniLibs.srcDir 'src/main/jniLibs' // jni库目录
           java.srcDirs = ['src'] // 指定java源代码目录
           resources.srcDirs = ['src'] // 指定resource目录
           aidl.srcDirs = ['src'] // 指定aidl目录
           renderscript.srcDirs = ['src'] // 指定source目录
        }
     debug.setRoot('build-types/debug') // 指定debug模式的路径
     release.setRoot('build-types/release') // 指定release模式的路径

}

四、packagingOptions属性——打包配置

    打包配置:
    1、pickFirsts:当出现重复文件,会使用第一个匹配的文件打包进入apk
    2、merges:当出现重复文件,合并重复的文件打入apk
    3、excludes:打包的时候排除匹配的文件
    packagingOptions {
            pickFirsts = ['META-INF/LICENSE']
            //这里不要直接=赋值,避免覆盖掉默认值
            merge 'META-INF/LICENSE'
            //这里不要直接=赋值,避免覆盖掉默认值
            exclude 'META-INF/LICENSE'
        }

五、compileOptions属性——Java 的版本配置

compileOptions {

// 在这里你可以进行 Java 的版本配置,

// 以便使用对应版本的一些新特性

 }

六、flavorDimensions属性—— 多维度理解(版本差异化打包)

flavorDimensions 从单词字面理解知道是 “风味维度”

是需要结合 “产品风味(即productFlavors)” 来一起使用的。

android {
    // 省略其他参数
    flavorDimensions 'ENV', "DEVICE_TYPE"
}

定义出两个维度:env和 device_type。一个参数一个维度

Android build.gradle文件_第5张图片

多维度理解
其实这涉及到了版本差异化打包的内容,如果说3.0以前的版本差异化打包更多的是为了厂商定制的,那么3.0以后的版本差异化打包就是在厂商的基础之上加入了机型,渠道等一些参数,变成了多个维度的产品。

也就是说之前的一个产品只有一个参数进行描述的话,现在就可以为其增加多个参数进行配置,比如A厂商的A渠道的A机型、A厂商的B渠道的C机型等,维度越多,产品的样式越发丰富。

 

好了,理论说完,接下来就是进行通俗易懂的一些示例了,只有实践才能让自己检验到真理。

新建项目,然后在app/build.gradle文件里配置两个风味维度(“company”,“channel”),如下:

defaultConfig {
        applicationId "com.voctex.flavorsapp"
        minSdkVersion 18
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 
        flavorDimensions "company","channel"
    }

然后进行产品的多维度配置:

productFlavors{
        //随便命名,建议根据该维度的具体信息进行命名
        companyA{
            dimension "company"
        }
        companyB{
            dimension "company"
        }
        channelA{
            dimension "channel"
        }
        channelB{
            dimension "channel"
        }
    }

配置完之后,sync构建一下项目。

打包构建之后就会出现多个维度的产品,对应如下,如图: 

Android build.gradle文件_第6张图片

可以理解为总共有两个维度,公司(company)和渠道(channel),这里公司的维度排前面(排序先后有要求,下面会讲到),所以所有的产品就是,A公司的A渠道产品,A公司的B渠道产品,B公司的A渠道产品,B公司的B渠道产品。
可见,增加维度之后,版本差异化的内容就更为丰富了。

上面说了,维度的定义先后是有要求的,不可随便,下面为了验证这个说法进行了一项测试,我们在productFlavors里给每一个特点产品定义一个常量,常量的值就是该特点产品的名字。如下:

 productFlavors{
        companyA{
            dimension "company"
            buildConfigField "String","FLAVOR_NAME","\"companyA\""
        }
        companyB{
            dimension "company"
            buildConfigField "String","FLAVOR_NAME","\"companyB\""
        }
        channelA{
            dimension "channel"
            buildConfigField "String","FLAVOR_NAME","\"channelA\""
        }
        channelB{
            dimension "channel"
            buildConfigField "String","FLAVOR_NAME","\"channelB\""
        }
    }

这里有个要注意的点就是在BuildConfig定义String的常量时,需要把双引号也加进去。

然后进行跟刚才一样的构建,对比几个风味维度的BuildConfig文件里的这个FLAVOR_NAME常量,会发现总是显示第一维度company的值,而第二维度channel的值并不存在,所以当产生多维度的产品时,定义的一些常量总是以第一维度的配置为准。结果如下:

BuildConfig.java 文件生成后会在app/build/generated/source/buildConfig/companyAChannelA/release/com/voctex/flavorsapp/BuildConfig.java

Android build.gradle文件_第7张图片

Android build.gradle文件_第8张图片

 Android build.gradle文件_第9张图片

 Android build.gradle文件_第10张图片

 实验证明,当你在各个维度各自定义了同一个常量的值,总是以第一维度的为准,只有第一维度的定义或者说是修改才是有效的。

 

七、productFlavors属性——不同渠道发布配置

productFlavors 从字面了解是“产品风味”。他需要和一个风味维度对接,否则会报错。

接着我们上面的例子,使用 productFlavors 定义维度上的风味,使用 dimension 关联。

productFlavors {
         // 在这里你可以设置你的产品发布的一些东西,
         // 比如你现在一共软件需要发布到不同渠道,
         // 且不同渠道中的包名不同,那么可以在此进行配置;
         // 甚至可以设置不同的 AndroidManifest.xml 文件。
         hebbe {
         }
         googlePlay {
         }
         solo {

            // applicationId 应用的包名,会覆盖 defaultConfig 中的 applicationId
            // applicationId 会替换 AndroidManifest.xml 中的 manifest 标签下 package 的 value
            applicationId "com.zinc.power"
            // 会追加在 applicationId 字符串的后面,形成最终的包名。
            applicationIdSuffix '.debug'
            // 风味的维度,指定我们当前风味所所属的维度
            dimension 'version'
            配置差异化的 logo 和 app名字
            manifestPlaceholders = [
                    logo    : "@drawable/logo_bear",
                    appName : "bear",
            ]
            // 配置签名
            signingConfig signingConfigs.xiaopenyou

         }
    }


七、dependencies属性——项目依赖关系配置


 // 指定当前项目的所有依赖关系:本地依赖、库依赖、远程依赖
 // 本地依赖:可以对本地 Jar 包或目录添加依赖关系
 // 库依赖:可以对项目中的库模块添加依赖关系
 // 远程依赖:可以对 jcenter 库上的开源项目添加依赖
 // 标准的远程依赖格式是 域名:组织名:版本号
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar']) // 本地依赖
     // 远程依赖,com.android.support是域名部分,appcompat-v7是组名称,26.1.0是版本号
     implementation 'com.android.support:appcompat-v7:26.1.0'
     implementation 'com.android.support.constraint:constraint-layout:1.0.2'
     implementation project(':hello') // 库依赖
     testImplementation 'junit:junit:4.12' // 声明测试用列库
     androidTestImplementation 'com.android.support.test:runner:1.0.1'
     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
 }
 

参考文章:Android ABI_android_abi_清风徐来辽的博客-CSDN博客

Android ABI_android_abi_清风徐来辽的博客-CSDN博客

Android 基础知识总结(一) build.gradle文件_build.gradle sourcesets_&岁月不待人&的博客-CSDN博客

Android 打包 flavorDimensions和productFlavors_flavordimensions打包_weixin_50386489的博客-CSDN博客

Android Studio3.0 flavorDimensions多维度理解(版本差异化打包)_安卓为什么要多维度打包_锐湃的博客-CSDN博客

你可能感兴趣的:(gradle)