美文网首页
gradle7 从上手到实践之核心API

gradle7 从上手到实践之核心API

作者: ddu_ | 来源:发表于2022-07-07 17:10 被阅读0次

1 获取 Project

命令行操作:

./gradlew projects

#输出
Root project 'HelloAndroid'
+--- Project ':app'
\--- Project ':TestLib'

Project 对象提供的方法:

//getAllprojects返回所有的project,包括当前project,返回类型:Set集合。
def getProjects() {
    println '-----------------'
    println 'Root Project'
    println '-----------------'

    this.getAllprojects().eachWithIndex { Project project, int index
        if(index == 0) {
            println "Root project : ${project.name}"
        } else {
            println "+--- project : ${project.name}"         
        }
        
    }
}

def getSubprojects() {
    println "-------------------------------------"
    println "Sub Project"
    println "-------------------------------------"

    // 获取所有子project
    this.getSubprojects().eachWithIndex { Project project, int index ->
        println "+---- Project: ${project.name}"
    }
}

/**
 * 获取父Project, 如果本身就是Root Project,返回null
 */
def getMyParentProject() {
    // The parent project, or null if this is the root project.
    if (this.getParent()) {
        println "the parent project name is : ${this.getParent().name}"
    } else {
        println "the parent project is null"
    }
}

/**
 * 获取Root Project,如果本身就是Root Project,返回自己,不会返回null
 */
def getMyRootProject() {
    // The root project. Never returns null.
    def name = this.getRootProject().name
    println "the root project name is: ${name}"
}

2 扩展属性

在 Gradle 对象中使用扩展属性

//settings.gradle 中添加
gradle.ext.testGradleExt=10
println gradle.testGradleExt

在 Project 对象中使用扩展属性

//在根 build.gradle 定义扩展属性

ext {
        compileSdkVersion = 25
        libAndroidDesign = 'com.android.support:design:25.0.0'
    }

//在子 build.gradle 中访问扩展属性
println rootProject.ext.compileSkdVersion
//进一步简化
println rootProject.compileSkdVersion
//扩展属性会被子Project继承,子Project可直接访问
println this.compileSdkVersion

利用扩展属性解决 gradle 脚本中的魔数问题:

//根目录下创建 commmon.gradle 文件:
//用来存放应用中的所有配置变量,统一管理,而不再是每个moudle里都自己写一份,修改起来更加的方便

ext {

  android = [compileSdkVersion   : 25,
             buildToolsVersion   : '25.0.0',
             applicationId       : 'com.youdu',
             minSdkVersion       : 16,
             targetSdkVersion    : 23,
             versionCode         : 1,
             versionName         : '1.0.0',
             multiDexEnabled     : true,
             manifestPlaceholders: [UMENG_CHANNEL_VALUE: 'imooc']]

  signConfigs = ['storeFile'    : 'youdo.jks',
                 'storePassword': 'rzq123456',
                 'keyAlias'     : 'qndroid',
                 'keyPassword'  : 'rzq123456']

  java = ['javaVersion': JavaVersion.VERSION_1_7]


  dependence = ['libSupportV7'           : 'com.android.support:appcompat-v7:25.0.0',
                'libSupportMultidex'     : 'com.android.support:multidex:1.0.1',
                'libCommonLibrary'       : ':vuandroidadsdk',
                'libPullAlive'           : ':lib_pullalive',
                'libCircleImageView'     : 'de.hdodenhof:circleimageview:2.1.0',
                'libSystembarTint'       : 'com.readystatesoftware.systembartint:systembartint:1.0.3',
                'libUmengAnalytics'      : 'com.umeng.analytics:analytics:latest.integration',
                'libUniversalImageLoader': 'com.nostra13.universalimageloader:universal-image-loader:1.9.5',
                'libOkhttp'              : 'com.squareup.okhttp3:okhttp:3.3.0',
                'libAutoScrollViewPager' : 'cn.trinea.android.view.autoscrollviewpager:android-auto-scroll-view-pager:1.1.2',
                'libSlidableActivity'    : 'com.r0adkll:slidableactivity:2.0.5',
                'libAndfix'              : 'com.alipay.euler:andfix:0.5.0@aar',
                'libLogger'              : 'com.orhanobut:logger:+',
                'libTinker'              : "com.tencent.tinker:tinker-android-lib:1.7.7",
                'libTinkerAndroid'       : "com.tencent.tinker:tinker-android-anno:1.7.7"]
}
//在根 build.gradle 中
apply from: this.file('common.gradle')
//其他地方引用:
rootProject.ext.android.compileSdkVersion

3 properties

gradle.properties:
gradle.properties 中定义扩展属性,只能定义 Key-value 属性

isLoadTest=false
mCompileSdkVersion=25

gradle 脚本中使用:

if(hasProperty('isLoadTest') ? isLoadTest.toBoolean() : false) {
    include ':Test'
}

android {
    compileSdkVersion mCompileSdkVersion.toInteger()
}

其他 properties:

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
ext."signing.keyId" = properties.getProperty("signing.keyId")
ext."signing.password" = properties.getProperty("signing.password")
ext."signing.secretKeyRingFile" = properties.getProperty("signing.secretKeyRingFile")

4 文件相关 API

//获取路径
println getRoootDir().absolutePath
println getBuildDir().absolutePath
println getProjectDir().absolutePath

//获取文件内容
def getContent(String path) {
    try {
        def file = file(path)  //相对于当前路径查找
        return file.text
    } catch(GradleException e) {
        println 'file not found..'
    }
    return null
}

//文本拷贝
copy {
    from file('youdo.jks')
    into getRootProject().getBuildDir()
}

//拷贝 apk 文件夹
copy {
    from file('build/outputs/apk/')
    into getRootProject().getBuildDir().path + '/apk/' 
}

//对文件树进行遍历
fileTree('build/outputs/apk') {
    fileTree.visit { FileTreeElement element ->
        println 'the file name is:' + element.file.name
        copy {
            from element
            into getRootProject().getBuildDir().path + '/test/'
        }
    }
}

5 依赖相关 Api

settings.gradle 中

pluginManagement { PluginManagementSpec spec -> 
    //配置 gradle 插件的依赖仓库地址,即我们 apply 的 gradle 插件去哪里下载?
    spec.repositories { RepositoryHandler handler ->
        handler.gradlePluginPortal()
        handler.google()
        handler.mavenCentral()
        handler.maven {
            name 'personal'
            url 'http://localhost:8081:/nexus/repositories/'
            credentials {
                username = 'admin'
                password = 'admin123'
            }
        }
    }
}

//根 build.gradle
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

//配置工程的依赖仓库地址
dependencyResolutionManagement { DependencyResolutionManagement management ->
    management.repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    management.repositories { RepositoryHandler handler ->
        handler.google()
        handler.mavenCentral()
    }
}

// app 下的 build.gradle
dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

依赖方法及其区别

  • implementation api:这种是我们最常用的方式,使用该方式依赖的库将会参与编译和打包。implementation 依赖方式所依赖的库不会传递。api 依赖方式会传递所依赖的库。
  • compileOnly:只在编译时有效,不会参与打包
  • runtimeOnly:只在生成apk的时候参与打包,编译时不会参与,很少用。
  • testImplementation:只在单元测试代码的编译以及最终打包测试apk时有效。
  • debugImplementation:debugCompile 只在debug模式的编译和最终的debug apk打包时有效
  • releaseImplementation:Release compile 仅仅针对Release 模式的编译和最终的Release apk打包

6 执行外部命令

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

7 Task

A Task represents a single atomic piece of work for a build, such as compiling classes or generating javadoc.

定义Task

task helloTask {
    println "i am helloTask" //配置阶段执行
}

//通过TaskContainer去创建Task
this.tasks.create(name:'helloTask2') {
    println 'i am helloTask2'
}

//对 Task 进行基本配置
task helloTask(group: 'imooc', description:'task study'){
    println 'i am helloTask  '
}

task helloTask {
    setGroup('imooc')
    setDescription('task study')
    println "i am helloTask" 
}

//doFirst doLast
task helloTask {
    println 'i am helloTask'  //配置阶段执行
    doFirst {
        println 'i am helloTask doFirst'   //执行阶段执行
    }
     doLast {
        println 'i am helloTask doLast'
    }
}

task.doFirst {
        println 'i am helloTask doFirst'
}

执行顺序与依赖

task taskX {
    doLast {
        println 'taskX'
    }
}

task taskY {
    doLast {
        println 'taskY'
    }
}

task taskZ(dependsOn:[taskX, taskY]) {
    dependOn this.tasks.findAll {
        task -> return task.name.startsWith('lib')
    }
    doLast {
        println 'taskZ'
    }
}

task lib1 << {println 'lib1'}
task lib2 << {println 'lib2'}
task nolib << {println 'nolib'}

8 Extension

8.1 什么是 extension

//先定义一个普通的java类,包含2个属性
class Foo {
    int age
    String username

    String toString() {
        return "name = ${username}, age = ${age}"
    }
}
//通过 Project 的 getExtensions 方法创建一个名为 foo 的Extension
Project.getExtensions().create("foo", Foo)

//脚本中配置Extension
foo {
    age = 30
    username = "hjy"
}

task testExt << {
    //能直接通过 project 获取到自定义的 Extension
    println project.foo
}

8.2嵌套的 Extension

class OuterExt {

    String outerName
    String msg
    InnerExt innerExt = new InnerExt()

    void outerName(String name) {
        outerName = name
    }

    void msg(String msg) {
        this.msg = msg
    }

    //创建内部Extension,名称为方法名 inner
    void inner(Action<InnerExt> action) {
        action.execute(innerExt)
    }


    String toString() {
        return "OuterExt[ name = ${outerName}, msg = ${msg}] " + innerExt
    }

}


class InnerExt {

    String innerName
    String msg

    void innerName(String name) {
        innerName = name
    }

    void msg(String msg) {
        this.msg = msg
    }

    String toString() {
        return "InnerExt[ name = ${innerName}, msg = ${msg}]"
    }

}

def outExt = getExtensions().create("outer", OuterExt)

outer {

    outerName "outer"
    msg "this is a outer message."

    inner {
        innerName "inner"
        msg "This is a inner message."
    }

}

task testExt  {
    doLast {
        println outExt
    }

}

相关文章

网友评论

      本文标题:gradle7 从上手到实践之核心API

      本文链接:https://www.haomeiwen.com/subject/aresbrtx.html