新东西015--AS下gradle参数解析

来源:互联网 发布:淘宝怎么刷信誉和销量 编辑:程序博客网 时间:2024/06/10 15:09

<span style="font-family: 'microsoft yahei'; background-color: rgb(255, 255, 255);">转载地址:http://blog.csdn.net/crazy1235/article/details/5046588</span>

apply plugin: 'com.android.application'android {    compileSdkVersion 23    buildToolsVersion "23.0.2"    defaultConfig {        applicationId "com.jacksen.multichannel"        minSdkVersion 14        targetSdkVersion 23        versionCode 1        versionName "1.0"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.1.1'    compile 'com.android.support:design:23.1.1'}

上面的就是一个项目gradle的基本配置。

apply plugin: 'com.android.application'

表示该module是一个app module,应用了com.android.application插件,也就是主程序。如果是一个第三方library,则应该是app plugin: ‘com.android.library’

buildTypes { } 表示构建类型。包括release和debug两种。可以在这里面配置启用混淆、zipAlign、签名信息等。

dependencies { } 里面是项目的依赖信息,包括jar包和第三方库等信息。

ApplicationId与PackageName的区别:

此前使用eclipse进行开发的时候,应用程序的包名是由manifest文件的package属性决定的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.xxx.xxxx"    android:versionCode="1"    android:versionName="1.0" >

然而在使用gradle构建的时候却多了一个applicationId。通常gradle中的applicationId和Manifest中的package是一样的。其实可以使二者一致。

官方解释说是:applicationId是你的应用在商店的唯一标识。而package是引用资源的路径名,也就是R文件的包名。

上面我们说到二者可以不一致,我们可以通过对不同的Flavor设置不同的applicationId,从而可以导出不同“包名”的apk,而不需要修改其他的代码。后面会仔细说明。


gradle的签名配置

我们通常运行项目都是使用debug的签名。不过有些使用到第三方sdk的时候,需要用到正式版的签名,通过打包正式签名的方式又不好调试。不过我们可以在gradle里面配置正式版的签名。

android {    signingConfigs {        config_release {            keyAlias 'releaseKey'            keyPassword '123456'            storePassword '123456'            storeFile file('key/releaseKey.jks')        }        config_debug {            keyAlias 'debugKey'            keyPassword '123456'            storePassword '123456'            storeFile file('key/debugKey.jks')        }    }    ......//省略其他配置}

这里配置了两个签名。jsk都放在app下面的key文件夹中。所以使用的是相对路径。

这里写图片描述

之前有人问我是怎么知道keyAlias 、keyPassword这些语法的。其实在项目的【Project Structure】中都可以找到。

这里写图片描述


配置buildTypes

一般在buildTypes{ }里面配置两个(release和debug):

buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            shrinkResources true //移除无效的resource文件,必须允许ProGuard才能生效            zipAlignEnabled true            buildConfigField "boolean", "APP_TYPE", "true"            manifestPlaceholders = [APP_NAME: "@string/app_name_release"]            signingConfig signingConfigs.config        }        debug {            buildConfigField "boolean", "APP_TYPE", "false"//            manifestPlaceholders = [APP_NAME: "@string/app_name_debug"]            applicationIdSuffix 'debug'        }    }

这里可配置的信息很多,比如:是否可以是debug模式、签名配置、混淆文件等。

图片名称


配置productFlavor

多渠道打包,关键就在于定义多个productFlavor。

在一个flavor里面可配置的信息很多。

productFlavors {        flavor_release {            buildConfigField "boolean", "APP_TYPE", "false"            applicationId 'com.jacksen.multichannel.release'            signingConfig signingConfigs.config_release            minSdkVersion 9            targetSdkVersion 15            versionCode 2            versionName '2.0.1'        }        flavor_debug {            minSdkVersion 10            applicationId 'com.jacksen.multichannel.debug'            signingConfig signingConfigs.config_debug            versionCode 5            versionName '5.0'        }    }

最主要的是可以在这里配置applicationId,就是我们上面一开始说的打包多个不同“包名”的apk。

这样有一个应用场景就是,我们一般通过debug版本进行测试之后,在进行release版本的测试。不过同一个applicationId的apk在一个测试机上只能存在一个。现在我们通过配置多个flavor对应多个applicationId,就可以在测试机上运行测试版和正式版两个apk了

图片名称


productFlavors{ } 与 buildTypes{ }里面的配置是多对多的关系。 
比如:

buildTypes {    release {...}    debug {...}}productFlavors {    flavor_1 {...}    flavor_2 {...}}

此时的配置可以打包出四个apk,分别是: 

这里写图片描述

我们在使用as的打包工具时,可以选择打包某一个Build type的某一个或多个Flavors:

图片名称

如果在gradle里面配置了签名信息,那么在【Generate Signed APK】的第一步填写的签名信息是以在gradle里面配置并引用的为准。

我们还可以借助gradlew命令来打包: 
比如打包flavor_1对应的release和debug版本:

这里写图片描述

图片名称

打包flavor_2对应的release版本:

这里写图片描述

实际上,我们不用再记住这些命令。AS里面的gradle插件就可以实现。 
在AS的右侧会有【Gradle】tab页面。打开之后,先刷新一下。会看到如下图示:

图片名称

通过双击右边的命令打包不同的版本。

除了build下面的命令,还有其他的命令,大家都可以尝试一下,根据名字应该就能知道什么意思,这里不多介绍了。


manifest占位符

在打包多个版本的时候,会遇到修改应用名称等需求。不同的flavor有要求不通的名称。此时可以在Manifest文件中使用占位符,然后在build.gradle中替换占位符就行了。

首先定义占位符:

application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="${APP_NAME}"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity            android:name=".LoginActivity"            android:label="${APP_NAME}">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>

在build.gradle中替换:

buildTypes {        release {            manifestPlaceholders = [APP_NAME: "@string/app_name1"]        }        debug {            manifestPlaceholders = [APP_NAME: "@string/app_name1"]        }    }

 productFlavors {        flavor_1 {            manifestPlaceholders = [APP_NAME: "@string/app_name1"]        }        flavor_2 {            manifestPlaceholders = [APP_NAME: "@string/app_name2"]        }    }

如果在productFlavors和buildTypes里面都进行了替换,那么是以productFlavors里面的为准。

如果不区分productFlavors和buildTypes的话,也可以在defaultConfig里进行替换:

defaultConfig {        manifestPlaceholders = [APP_NAME: "@string/app_name_release"]    }

其实defaultConfig也是productFlavors的一个子集。


添加自定义字段

Gradle在generateSources阶段为每一个flavor生成两个BuildConfig.java文件(对应在release和debug文件夹下)。

BuildConfig类默认会提供一些常量字段。

public final class BuildConfig {  public static final boolean DEBUG = Boolean.parseBoolean("true");  public static final String APPLICATION_ID = "com.jacksen.multichannel";  public static final String BUILD_TYPE = "debug";  public static final String FLAVOR = "";  public static final int VERSION_CODE = 1;  public static final String VERSION_NAME = "1.0";}

虽然通过上面的操作,我们可以同时打包出一个debug版本和一个release版本。但是我们还需要运行的时候有不同的表现。比如,release版本不显示一些控件。

令人惊奇的是,我们可以通过buildConfigField在gradle里面自定义一些字段。

buildConfigField "String", "APP_TYPE", "debug"

我们可以查看buildConfigField的源码:

/**     * Adds a new field to the generated BuildConfig class.     *     * <p>The field is generated as: <code><type> <name> = <value>;</code>     *     * <p>This means each of these must have valid Java content. If the type is a String, then the     * value should include quotes.     *     * @param type the type of the field     * @param name the name of the field     * @param value the value of the field     */    public void buildConfigField(            @NonNull String type,            @NonNull String name,            @NonNull String value) {        ClassField alreadyPresent = getBuildConfigFields().get(name);        if (alreadyPresent != null) {            logger.info(                    "BuildType(${getName()}): buildConfigField '$name' value is being replaced: ${alreadyPresent.value} -> $value");        }        addBuildConfigField(AndroidBuilder.createClassField(type, name, value));    }

注释写的很详细。该方法就是添加一个field到BuildConfig类中。三个参数都是不可为空的。

添加完毕之后,就可以在代码中使用了:

textView.setText("BuildConfig.APP_TYPE : " + BuildConfig.APP_TYPE);

自定义导出APK的名称

我直接上代码吧。

/*applicationVariants.all {        variant ->            variant.outputs.each {                output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {//                        def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")                        def apkType = ""                        if (variant.flavorName.equals("releaseFlavor")){                            apkType = "release"                        }else if(variant.flavorName.equals("debugFlavor")){                            apkType = "debug"                        }                        def fileName = new File(output.outputFile.getParent(), "app-" + apkType + "-${variant.versionName}.apk")//                        output.outputFile = new File(outputFile.parent, fileName)                        output.outputFile = fileName                    }            }    }*/    applicationVariants.all {        variant ->            variant.outputs.each {                output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {                        def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionCode}-${defaultConfig.versionName}.apk")                        output.outputFile = new File(outputFile.parent, fileName)                    }            }    }

这里有两种方式,大家运行一下测试一下就明白了。

以上就是我对gradle的一些认识~~~

0 0
原创粉丝点击