Gradle_05 自定义插件+Android对gradle的扩展+Jenkins

657 阅读3分钟

1.Settings

对应安卓工程settings.gradle文件

2.SourceSet

android{
    //指定jniLibs .so存放位置 libs(默认在src/main/jniLibs下)
    sourceSets{
        main {
            jniLibs.srcDirs=['libs']
        }
    }
    //资源分包(很奇怪在我的项目中编译通不过)
    sourceSets{
        main{
            res.srcDirs = ['res/main/res','res/main/res_player']
        }
    }
}

* 3.自定义插件(重要)

①在项目工程中创建buildSrc插件工程,删除多余目录,修改build.gradle配置, 按照约定创建groovy包和resources包,如图:

②创建groovy类GradleStudyPlugin(程序入口),resources下创建包名+.properties文件,写入导出类,app/build.gradle导入插件,同步项目,可以看到输出
GradleStudyPlugin.groovy

package com.dsh.gradle.study
import org.gradle.api.Plugin
import org.gradle.api.Project

class GradleStudyPlugin implements Plugin<Project>{

    /**
     * 插件被引入时要执行的方法
     * @param target The target object 引入当前插件的project
     */
    @Override
    void apply(Project project) {
       println 'hello Plugin ...'+project.name
    }
}

properties文件

implementation-class=com.dsh.gradle.study.GradleStudyPlugin

app/build.gradle

apply plugin: 'com.dsh.gradle.study'

③创建VersionInfoExtension类,与外部通信,GradleStudyPlugin添加执行代码,同时在app/build.gradle中为插件自定义参数
VersionInfoExtension

package com.dsh.gradle.study
/**
 * 与自定义Plugin进行参数传递
 */
class VersionInfoExtension{

    String versionCode
    String versionInfo
    String versionName
    String fileName

    VersionInfoExtension(){

    }

    @Override
    String toString() {
        """|versionCode = ${versionCode}
            |versionInfo = ${versionInfo}
            |versionName = ${versionName}
            |fileName = ${fileName}
        """.stripMargin()
    }
}

GradleStudyPlugin.groovy

package com.dsh.gradle.study
import org.gradle.api.Plugin
import org.gradle.api.Project

class GradleStudyPlugin implements Plugin<Project>{

    /**
     * 插件被引入时要执行的方法
     * @param target The target object 引入当前插件的project
     */
    @Override
    void apply(Project project) {
       //println 'hello Plugin ...'+project.name
       project.extensions.create('dshJavaVersionInfo',VersionInfoExtension)
    }
}

app/build.gradle

//为自定义插件传递参数
dshJavaVersionInfo{
    versionName = rootProject.ext.android.versionName
    versionCode = rootProject.ext.android.versionCode
    versionInfo = 'App的第6个版本,我有自定义插件功能了哦'
    fileName = 'releases.xml'
}

④自定义task,移植versionInfo.gradle部分代码,实现真正的业务需求,在app/build.gradle中导入task,执行 ./gradlew updateVersionInfo命令,即可以看到releases.xml的更新
VersionInfoTask

package com.dsh.gradle.study

import groovy.xml.MarkupBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

/**
 * 自定义Task,实现维护版本信息功能
 */
class VersionInfoTask extends DefaultTask{

    VersionInfoTask(){
        group = 'dsh'
        description = 'update the release infoo'
    }

    /**
     * 执行于gradle执行阶段的代码
     * @return
     */
    @TaskAction
    void doAction(){
        updateInfo()
    }

    //真正的将Extension类中的信息写入指定文件中
    private void updateInfo(){
        //获取将要写入的信息
        String versionCodeMsg = project.extensions.dshJavaVersionInfo.versionCode
        String versionNameMsg = project.extensions.dshJavaVersionInfo.versionName
        String versionInfoMsg = project.extensions.dshJavaVersionInfo.versionInfo
        String fileName = project.extensions.dshJavaVersionInfo.fileName
        def file = project.file(fileName)
        //将实体对象转化为xml格式数据
        def sw = new StringWriter()
        def xmlBuilder = new MarkupBuilder(sw)
        if (file.text !=null &&file.text.size()<=0){
            //文件中没有内容
            xmlBuilder.release{
                release{
                    versionCode(versionCodeMsg)
                    versionName(versionNameMsg)
                    versionInfo(versionInfoMsg)
                }
            }
            file.withWriter {writer -> weiter.append(sw.toString())}
        }else{
            //已有版本信息
            xmlBuilder.release{
                versionCode(versionCodeMsg)
                versionName(versionNameMsg)
                versionInfo(versionInfoMsg)
            }
            //将生成的xml数据插入到根节点之前
            def lines = file.readLines()
            def lengths = lines.size()-1
            file.withWriter {writer ->
                lines.eachWithIndex{ String line, int index ->
                    if(index !=lengths){
                        writer.append(line +"\r\n")
                    }else if(index == lengths){
                        writer.append("\r\n"+sw.toString()+"\r\n")
                        writer.append(lines.get(lengths))
                    }
                }
            }
        }
    }

}

app/build.gradle

import com.dsh.gradle.study.VersionInfoTask
...
...
...
//自定义插件功能task执行
task updateVersionInfo(type:VersionInfoTask)

4.Android对gradle的拓展

利用各种变体进行打包配置

apply plugin: 'com.android.application'

android {
    //config.gradle 扩展属性 ext
    // compileSdkVersion this.rootProject.ext.compileSdkVersion
    // 也可以直接调用
    compileSdkVersion this.compileSdkVersion
    buildToolsVersion this.rootProject.ext.android["buildToolsVersion"]

    defaultConfig {
        applicationId applicationID//使用gradle.properties 拓展属性
        minSdkVersion this.rootProject.ext.android["minSdkVersion"]
        targetSdkVersion this.rootProject.ext.android["targetSdkVersion"]
        versionCode this.rootProject.ext.android["versionCode"]
        versionName this.rootProject.ext.android["versionName"]
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    //指定jniLibs .so存放位置 libs(默认在src/main/jniLibs下)
    sourceSets{
        main {
            jniLibs.srcDirs=['libs']
        }
    }
    //    //资源分包
    //    sourceSets{
    //        main{
    //            res.srcDirs = ['res/main/res','res/main/res_player']
    //        }
    //    }

    buildTypes {
        //自定义applicationId,appName
        debug {
            applicationIdSuffix applicationID_test
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            manifestPlaceholders = [APP_NAME    : getAppName('debug')]
            //--------------------------------------------------------------------------------
            debuggable true //默认false,是否开启断点调试
            jniDebuggable true //默认false,是否开启jni的断点调试
            renderscriptDebuggable true //默认false,是否开启 renderscript 断点调试
            renderscriptOptimLevel 2 //renderscript的版本号
            minifyEnabled true //默认false,是否混淆的开关
            pseudoLocalesEnabled true //默认false,是否支持本地化整理
            versionNameSuffix '.10' //版本名的后缀
            zipAlignEnabled false //默认true,是否进行zip align优化
            buildConfigField "boolean", "IS_DEBUG", "true"//为BuildConfig类创建一个常量,类型为boolean,变量名为IS_DEBUG,值为true
            resValue "string", "name", "value" //在strings.xml中创建一个名为name,值为value的一个字符串资源
        }

        release {
            applicationIdSuffix applicationID_release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            manifestPlaceholders = [APP_NAME    : getAppName('release')]
        }

    }
    
    //配置签名方式,这里配置会覆盖defaultConfig中配置的签名方式
    signingConfigs {
        release {
            storeFile file("../appsign")
            storePassword "123456"
            keyAlias "dsh"
            keyPassword "123456"
        }
        buildTypes {
            debug {
                signingConfig signingConfigs.release
            }

            release {
                signingConfig signingConfigs.release
            }
        }
    }

    //多渠道打包,三方统计
    flavorDimensions "default"
    productFlavors{
        DshJava{}
        _xiaomi{}
        _huawei{}
        _oppo{}
        _vivo{}
//        productFlavors.all { flavor ->
//            flavor.manifestPlaceholders = [APP_DOWNLOAD_CHANNEL: name]
//        }
    }

    //apk输出命名规范
    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def releaseApkName = "app-v" +
                    "${defaultConfig.versionName}-" +
                    "${buildTime()}-"+
                    "${variant.buildType.name}.apk"
            outputFileName = new File(releaseApkName)
        }
    }

}

def getAppName(String type) {
    return new String("JavaStudy_${type}")
}

def buildTime() {
    def date = new Date()
    def formattedDate = date.format('yyyy_MM_dd')
    return formattedDate
}


//为应用程序添加第三方依赖
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
}

5.Jenkins

Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。
参考资料
Jenkins官网
Android Jenkins+Git+Gradle持续集成