Gradle高阶-Project详解(完结)

6,139 阅读3分钟

上节我们讲到project的属性相关的一些东西,今天学习project剩余部分

文件相关

文件常见操作相关api,相比之下,这部分内容就比较简单一些了

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

  • 文件操作相关api
  1. 文件定位(file)
    以当前project来寻找文件(如果在根工程下,那么就会在根工程中寻找文件,如果找不到的话就会报FileNotFoundException)
//调用方法
println getContent('common.gradle')

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

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

其实没有什么不同,都是传递一个file文件路径,
使用file方法则不需传入一个绝对路径,可以自动转化为相当路径      
  1. 文件拷贝(copy)
    可以拷贝文件或者是文件夹
from:文件(夹)来源路径       
into:文件(夹)拷贝目的路径 

copy{
   from file('build/outputs/apk/')
   into getRootProject().getBuildDir().path+'/apk/'
   exclude{}
   rename{}
}
  1. 文件树遍历(FileTree)
fileTree('build/outputs/apk/'){
    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.libSupportV7
  1. 远程仓库地址
 compile 'com.github.chrisbanes:PhotoView:1.3.0'

常常在使用的时候经常会出现依赖冲突的问题,因此导致编译时候就就报错,此时我们就需要移除冲突的依赖库,需要通过使用exclude进行排除操作
比如解决v4包的冲突,我们可以采用下面的两种方式(选一即可)

compile 'com.github.chrisbanes:PhotoView:1.3.0'{
     exclude module:'support-v4'
     transitive false //禁止传递依赖
 }
compile 'com.github.chrisbanes:PhotoView:1.3.0'{
     exclude group:'com.android.support'
 }

常用的依赖有compile和provided,那两者的区别在哪?

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'
            }
        }
        
    }
}

最后在生成apk文件后,再执行./gradlew apkcopy 就可以将文件移动到指定位置了

到这里project相关的内容大体就告一段落了,下面进行总结

小结

  • 了解Project的定义,组织结构以及作用
  • 掌握gradle核心api的使用