首页 > 代码库 > Android studio使用之[gradle的使用]

Android studio使用之[gradle的使用]

Android studio使用之[gradle使用]

  • gradle的相关介绍
  • gradle相关命令
  • 使用gradle进行多渠道打包

gradle的相关介绍

在Android Studio中有一个不可或缺的构建工具,就是gradle,我们所有的打包等操作都是需要使用gradle来进行的,往往在做android开发的时候我们都知道有个工具是叫gradle,那gradle是什么?为什么要有这样一个gradle工具?以及我们应该怎么去使用这样一个gradle呢?可能多数的程序员对这一块相对来说都是比较陌生的,只知道使用,但是却往往很多时候忽略了它的真正含义。在这里我就简单说一下我自己的理解。不喜勿喷!!!

1:首先是gradle的相关概念:

什么是gradle???
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。(简单总结下来也就是gradle就是一款相比以前来说更加智能一点的构建工具,其的诞生是基于jvm构建工具,解决的是繁琐的配置文件),那什么是构建????如果你需要盖一间房子,你是不是需要把砖,瓦,水泥,钢筋都需要准备好,然后请一个工人来,然后工人给你盖房子。我们也就可以把这一整个流程看做是一个构建的流程,首先你需要将一个完整的设计图纸和材料(整个项目),然后工人通过将材料组合,形成你图纸上想要的房子,但是如果工人出现偏差(参数修改),盖出来的房子就会改变,如果是材料或者图纸有点改变。那工人所盖的房子可能也会有一些偏差。可以简单的理解下,这是否就是一个完整的构建流程。

其实在15年初使用android studio的时候,那个时候gradle有时候都是需要自己去下载,配置的,而与现在的更加智能的android studio2.2版本相比,在install的时候,已经会自动默认去更新一些gradle版本了

2:先来看一下在android studio中安装的默认gradle的位置吧。当然也可以进行别的配置:

技术分享

这是我android studio目录下,最新的gradle的相关位置

技术分享

当然,还有在window下gradle的相关配置参数之类的,这个主要是在Administrator文件夹下的,后续下载的所有gradle版本貌似都在这个文件夹下面,有兴趣的可以自己去找一下

3:跟着我来查看android studio项目中的gradle脚本
技术分享

从图上可以看到,在整个项目中有这样的几块都是与gradle相关的,当然每一个都是很重要的

先来说说项目的app/build.gradle吧:

//声明是android 应用程序,同样做java的同学也可以声明为java相关的
apply plugin: ‘com.android.application‘

//定义release版本的打包时间
def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

android {
    //编译的sdk的版本
    compileSdkVersion 25
    //build tools的版本
    buildToolsVersion "25.0.1"
    //默认相关的配置
    defaultConfig {
        //包名
        applicationId "com.zzf.camera.helloworld"
        //最小的sdk(向下兼容)
        minSdkVersion 22
        //目标sdk
        targetSdkVersion 25

        // dex突破65535的限制
        multiDexEnabled true

        //版本号
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

//签名工具
signingConfigs {
    debug {
    // No debug config
    }
    release {
        storeFile file("../yourapp.keystore")
        storePassword "your password"
        keyAlias "your alias"
        keyPassword "your password"
    }
}

// java版本
compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
}

//对应用原始编译出来的apk进行名称的修改(默认编译出来的是app-debug.apk和app-release-unsigned.apk,此处都是未进行签名的)
android.applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            def fileName
            if (outputFile != null && outputFile.name.endsWith(‘.apk‘)) {
                if (variant.buildType.name.equals(‘release‘)) {
                fileName = "Hello.apk"
            } else if (variant.buildType.name.equals(‘debug‘)) {
                fileName = "Hello.apk"
            }
            output.outputFile = new File(outputFile.parent, fileName)
        }

    }
}

// 移除lint检查的error
lintOptions {
        abortOnError false
}

//构建的类型,是debug版本还是release版本
    buildTypes {
        //debug版本的参数配置
        debug{
            signingConfig signingConfigs.debug
        }
        //release版本相关的版本配置
        release {
            //是否进行混淆
            minifyEnabled false
            //混淆相关的文件的位置
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
            signingConfig signingConfigs.release
        }
    }
}

//新建的工程,所以依赖的都是基础jar
dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {
        exclude group: ‘com.android.support‘, module: ‘support-annotations‘
    })
    compile ‘com.android.support:appcompat-v7:25.3.1‘
    compile ‘com.android.support.constraint:constraint-layout:1.0.2‘
    testCompile ‘junit:junit:4.12‘
}

以上就是关于文件的比较基本的相关配置

先来说说项目的gradle/wrap/目录吧:

技术分享

gradle-wrapper.jar: 当前此project的所有构建工作主要就是依赖这样的一个jar包,后面会展示一下相关这个jar的具体内容。
gradle-wrapper.properties:类似于脚本配置文件,在引用的时候,需要给gradle-wrapper.jar提供相关的引用路径,一般情况下这个都是在项目建立的时候,整个gradle-wrapper.jar相关的调用路径等都是已经默认生成好了,所以是不需要再进行修改的

#Sat Apr 22 12:50:57 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

整个工程构建部分的gradle

对应的是整个project目录下的,包括了所有的sub_project和modules都试用

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    //仓库
    repositories {
        jcenter()
    }
    dependencies {
        classpath ‘com.android.tools.build:gradle:2.3.1‘

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

内容主要包含了两个方面:一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。另一个是声明了android gradle plugin的版本

整个工程构建部分的Setting.gradle(系统自动更新,一般情况下不需要我们进行修改)
没有依赖module项目的操作

include ‘:app‘

依赖了包名为com.zzf.device.mediacodec项目之后

include ‘:app‘, ‘:com.zzf.device.mediacodec‘

整个工程构建部分的可执行的gradlew.bat

技术分享

所有的gradle相关的执行全靠这个可执行命令,所有在整个构建的过程中,我们既可以去依赖android studio去帮我们构建,同时也可以使用gradlew.bat这样一个执行脚本,去构建

瞧一瞧,看一看,这个脚本都写了些什么??

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no ‘java‘ command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

里面有几个比较重要的代码:
1://设置java.exe
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if “%ERRORLEVEL%” == “0” goto init:

2://设置gradle-wrapper的目录
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

所以就可以看出来了,其实这个脚本大概的意思是
java -jar gradle-wrapper.jar//事实上就是去执行这个jar

简单了解gradle-wrapper.jar包源码:
技术分享

整个jar包的Main函数是从GradleWrapperMain.class这里开始的,它会去从整个执行列表中去获取参数,然后在进行switch的过程,具体的代码不会在这里进行详细介绍。

public static void main(String[] args)
    throws Exception
  {
    File wrapperJar = wrapperJar();
    File propertiesFile = wrapperProperties(wrapperJar);
    File rootDir = rootDir(wrapperJar);

    CommandLineParser parser = new CommandLineParser();
    parser.allowUnknownOptions();
    parser.option(new String[] { "g", "gradle-user-home" }).hasArgument();
    parser.option(new String[] { "q", "quiet" });

    SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
    converter.configure(parser);

    ParsedCommandLine options = parser.parse(args);

    Properties systemProperties = System.getProperties();
    systemProperties.putAll(converter.convert(options, new HashMap()));

    File gradleUserHome = gradleUserHome(options);

    addSystemProperties(gradleUserHome, rootDir);

    Logger logger = logger(options);

    WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile, logger);
    wrapperExecutor.execute(args, new Install(logger, new Download(logger, "gradlew", wrapperVersion()), new PathAssembler(gradleUserHome)), new BootstrapMainStarter());
  }

gradle相关命令(不进gradle-wrapper.jar看源码,讲原理,只讲使用)

技术分享

先进入这个文件所在的目录下吧

技术分享

执行可执行命令
技术分享

传入的参数都是传入到jar中去执行的。

命令 执行意义
-v 版本号
clean 清除app/目录下的build文件夹
build 检查依赖并编译打包
assembleDebug 编译并打Debug包
assembleRelease 编译并打Release的包
installRelease Release模式打包并安装
uninstallRelease 卸载Release模式包
installDebug Debug模式打包并安装
uninstallDebug 卸载Debug模式包

具体的执行就不在这里执行了


使用gradle进行多渠道打包

第一步 在AndroidManifest.xml里配置PlaceHolder

<meta-data
android:name="UMENG_CHANNEL"
android:value=http://www.mamicode.com/"${UMENG_CHANNEL_VALUE}" />

第二步 在build.gradle设置productFlavors

android {
    productFlavors {
    xiaomi {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
    }
    _360 {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
    }
    baidu {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
    }
    }
}

或者
android {
    productFlavors {
        xiaomi {}
        _360 {}
        baidu {}
        wandoujia {}
    }
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}

第三步:执行命令

直接执行 ./gradlew assembleRelease 进行全部打包的过程
直接执行./gradlew assembleBaidujia,进行单个渠道的打包
直接执行./gradlew assembleBaiduRelease进行豌豆荚release版本的渠道打包

以上就是对gradle的一些简单的了解
欢迎持续访问博客

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    Android studio使用之[gradle的使用]