Gradle Project 总结

259 阅读3分钟

Project详解

  • project相当于Android中的activity的入口一样,是构建gradle程序的入口。
  • 判断是不是一个project的关键就是是否包含build.gradle文件,如果将build.gradle文件删除掉,那么这个目录就相当于一个普通的文件夹。
  • 在gradle中Android工程中的每一个module都是一个project,我们可以通过执行gradlew projects来查看所有project。
C:\Users\zhongyu\Desktop\Test>gradlew projects

> Configure project :app
hello hello hello

> Task :projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'Test'
\--- Project ':app'

Project 核心Api

  • 紫色:当前project拥有操作父project和管理子project的能力,管理生命周期的能力。

Gradle Project Api

获取所有project

getProjects()

def getProjects(){
    this.getAllprojects().eachWithIndex{ Project project, int i ->
        if (i==0){
            println "Root Projects ':${project.name}'"
        }else {
            println "+--- project ':${project.name}' "
        }
    }
}

//输出
Root Projects ':Test'
+--- project ':app'

获取所有子project

getSubProjects()

def getSubProjects() {
    this.getSubprojects().eachWithIndex { Project project, int i ->
        println "+--- project ':${project.name}' "
    }
}

获取父project

getParentProject()

def getParentProject(){
    def name=this.getParent().name
    println "the parent project name is :${name}"
}

//输出
the parent project name is :Test

project实战

apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.imooc.demo"
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 32
    }

}

dependencies {
    api fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

通过定义变量取代无意义字符

apply plugin: 'com.android.application'
def mCompileSdkVersion=28
def libCompat='com.android.support:appcompat-v7:28.0.0'
android {
    compileSdkVersion mCompileSdkVersion
    defaultConfig {
        applicationId "com.lcf.demo"
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 32
    }

}

dependencies {
    api fileTree(include: ['*.jar'], dir: 'libs')
    implementation libCompat
     implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

通过ext。

apply plugin: 'com.android.application'

ext{
     mCompileSdkVersion=28
     libCompat='com.android.support:appcompat-v7:28.0.0'
}
android {
    compileSdkVersion this.mCompileSdkVersion
    defaultConfig {
        applicationId "com.imooc.demo"
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 32
    }

}

dependencies {
    api fileTree(include: ['*.jar'], dir: 'libs')
    implementation  this.libCompat
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

通过subprojects。

buildscript {
    ...
}

allprojects {
    ...
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
subprojects{
    ext{
        mCompileSdkVersion=28
        libCompat='com.android.support:appcompat-v7:28.0.0'
    }
}

通过子Project中所有属性都会继承父Project中的属性。

buildscript {
    ...
}

allprojects {
    ...
}

ext{
        mCompileSdkVersion=28
        libCompat='com.android.support:appcompat-v7:28.0.0'
}

通过configs.gradle。

//configs.gradle
ext{
    android=[
        applicationId :"com.lcf.demo"
        minSdkVersion :17
        targetSdkVersion :28
        versionCode :32
    ]
    signConfigs=[
    ]
    java=[
    ]
    dependence=[
    
        'design': 'com.android.support:design:28.0.0'
        'support-v4': 'com.android.support:support-v4:28.0.0'
        'recyclerview': 'com.android.support:recyclerview-v7:28.0.0'
    ]
}

//root build.gradle
apply from: this.file('configs.gradle')
buildscript {
}

allprojects {
}

// app build.gradle
apply plugin: 'com.android.application'
android {
    compileSdkVersion this.mCompileSdkVersion
    defaultConfig {
        applicationId rootProjet.ext.android.applicationId
        minSdkVersion rootProjet.ext.android.minSdkVersion
        targetSdkVersion rootProjet.ext.android.targetSdkVersion
        versionCode rootProjet.ext.android.versionCode
    }

}

dependencies {
    compile rootProjet.ext.dependence.design
    compile rootProjet.ext.dependence.support-v4
    compile rootProjet.ext.dependence.recyclerview
}

通过gradle.properties

isDebug=false
mCompileSdkVersion=25

//include ':Test'
//现在通过isDebug属性来确定是否加载该模块
if(hasProperty('isDebug')?isDebug.toBoolean():false){
    include ':Test'
}

注意:

  • 这个文件中的属性只能用key:value的形式。
  • 使用compileSdkVersion的地方要写成mCompileSdkVersion.toInteger()

扩展属性总结:

  • 通过ext。
  • 通过gradle.properties

文件相关

  1. 路径获取相关api
//获取根工程的文件路径
println "root path:"+getRootDir().absolutePath
//获取build文件路径
println "build path:"+ getBuildDir().absolutePath
//当前工程文件路径
println "this project path:"+getProjectDir().absolutePath
  1. 文件操作相关api

文件定位

//调用方法
println getContent('common.gradle')

def getContent(String path){
    try{
      //返回多个文件路径 files
      //相当于从当前project进行查找
     def file =file(path)  
      //查找到后获取文件内容
      return file.text
    }catch (GradleException e){
        println "file is not found..."
    }
    return null
}

问:file方法和new一个file方法有什么不同?

  • 使用file方法不需传入一个绝对路径,可以自动转化为相当路径。

文件拷贝

copy{
   from file('build/outputs/apk/') //来源
   into getRootProject().getBuildDir().path+'/apk/' //目标
   exclude{} //不拷贝的文件
   rename{} //重命名
}
  1. 文件树遍历
fileTree('build/outputs/logs/'){
    FileTree fileTree->fileTree.visit{
        FileTreeElement element->
            println 'the file name is :'+element.file.name
        copy{
            from element.file
            into getRootProject().getBuildDir().path+'/test/'
        }
    }
}

依赖相关

buildscript 通过查看buildscript源码,我们可以知道它的闭包参数是一个ScriptHandler,发现两个很眼熟的方法。

//配置工程的仓库地址 RepositoryHandler
void repositories(Closure configureClosure)
//配置工程“插件地址”
void dependencies(Closure configureClosure)

buildscript{
    ScriptHandler script->
    script.repositories{
        RepositoryHandler repository->
        repository.jcenter()
        repository.mavenCentral()
        repository.movenLocal()
        repository.maven(){
            //设置组织名字
            name 'personal'
            //仓库地址
            url 'http://localhost:8081:/nexus/repositories'
            //设置账户密码
            credentials{
                username='admin'
                password='123456'
            }
        }
        
    }
    
    script.dependencies{
         classpath 'com.android.tools.build:gradle:2.2.2'
    }
}

//简写版
buildscript{
   repositories{
      jcenter()
      mavenCentral()
      movenLocal()
        maven(){
            name 'personal'
            url 'http://localhost:8081:/nexus/repositories'
            credentials{
                username='admin'
                password='123456'
            }
        }
        
    }
    dependencies{
    //依赖gradle所需要的第三方插件
        classpath 'com.android.tools.build:gradle:2.2.2'
    }
}

app.build中单独的dependencies依赖,则表示的是为该应用程序添加第三方库的依赖。

  1. 本地文件依赖
 compile fileTree(include:['*.jar'].dir:'libs')
  1. 本地lib工程
compile rootproject.ext.dependence.libSupport
  1. 远程仓库地址
 compile 'com.github.chrisbanes:PhotoView:1.3.0'
  1. 依赖冲突
compile 'com.github.chrisbanes:PhotoView:1.3.0'{
     exclude module:'support-v4'//第一种
     exclude group:'com.android.support'//第二种
     transitive false //禁止传递依赖
 }

  • compile:会将第三方依赖中的所有资源和文件都会打入到apk中
  • provided:占位编译,只提供编译支持,但是不会写入apk。(第三方库常用)

外部命令执行

task(name:'apkcopy'){
    doLast{
        //gradle的执行阶段执行
        def sourcePath=this.buildDir.path+'/outputs/apk'
        def desationPath='/users/lcf/Downloads/'
        def command="mv -f ${sourcePath} ${desationPath}"
        exec{
            try{
                executable 'bash'
                args '-c' command
                println 'the command is success'
            }catch(GradleException e){
                println 'command is failed'
            }
        }
        
    }
}