【android 应用】gradle 中定制化编译,以及相关设置

最近需求说要做一个定制化编译,然后就开始研究gradle。以前以为很简单就是个编译工具,偶尔配置下就好了。最后被打脸了,发现对其一点都不了解---一无所知。研究了三天只研究了个皮毛,写下来总结下以后方便查阅。


一、gradle简介

1.Android Gradle基础

android应用程序使用开源工具Gradle构建。Gradle一种艺术API,非常容易的支持定制,并且在java世界有着广泛的应用。Android为了实现编译、打包等,开发者开发了Android插件为Gradle添加了一系列的新特征,特别是在构建Android app上的应用,包括:构建类型、多样化、签名配置、库文件工程等等功能。

Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。

1.1 Android Gradle构建文件

在我们使用Android Studio工具开发Android应用的时候,当创建一个新的Android工程,默认的Gradle构建文件包括了setting.gradlebuild.gradleapp/build.gradle。具体位置如图所示

build.gradle:配置其他子Project的,添加任务。

settings.gradle:它里边用来告诉Gradle,这个multiprojects包含多少个子Project。

二、任务Task建立

2.1、添加和执行任务

1、添加

在根目录或者app目录下的build.gradle中添加

task startDelTask {
    doLast {
        //remove "ijkplayer-java/"
        println "this is startDelTask"
    }
}

2、运行

通过图形界面运行

双击图形界面中的startDelTask即可。我的Task是添加在根目录下的所以在根目录下中other目录(也可随便点一个,输入查找,选中后直接输入即可查找)

通过命令运行

gradlew startDelTask

2.2、在编译前执行

1、每一个编译都行

task startDelTask {
    doLast {
        //remove "ijkplayer-java/"
        println "this is startDelTask"
    }
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn startDelTask
}

2、要判断名称

project.tasks.whenTaskAdded { Task theTask ->
    if (theTask.name == 'assembleDebug') {
        theTask.dependsOn(tangTangTest)
        theTask.mustRunAfter(tangTangTest)				// diyTask在assembleRelease之前执行
    }
}

2.3、在任务后执行

Task diyTask = project.task('diyTask') {
    doLast {
        Utils.println("diy task run")
    }
}

project.tasks.whenTaskAdded { Task theTask ->
    if (theTask.name == 'assembleRelease') {
        theTask.dependsOn(diyTask)            // 编译完apk之后再执行自定义task
    }
}

三、多渠道定制化

多渠道还可以定制很多东西详细这里就不介绍了。还有什么占位符修改androidmaniface.xml修改也没有介绍,网上很多资料,感兴趣的可以去网上学习下。

android{
    ... ...
    defaultConfig {
        ... ...
        flavorDimensions "default"
    }
    ... ...
    productFlavors {
        OTT {
            dimension "default"
            //设置buildConfig参数
            buildConfigField "String", "FLAVORS_TYPE", '"OTT"'
        }
        OTT_DVB {
            dimension "default"
            buildConfigField "String", "FLAVORS_TYPE", '"OTT_DVB"'
        }
    }

    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
    }
}

四、AndroidManifest文件的替换

4.1、通过参数直接配置

首先在/src/main下建两个文件夹(不一定一样命名)。debug和release。两个文件夹中放入不同的AndroidManifest.xml

然后在当前不要打包不同AndroidManifest文件的Module的build.gradle中写入以下代码:

判断条件通过传参,或者全局定义。

  sourceSets {
        main {
            if (条件判断) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }

//如下5.1传参
    sourceSets {
        main {
            println "------>${getTinkerIdValue()}"
            if (getTinkerIdValue().equals("OTT")) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }

4.2、拷贝到编译目录上去

编译目录:VPSClient\app\build\intermediates\merged_manifests\OTTRelease

android {
    ... ...
    applicationVariants.all { variant ->
        variant.outputs[0].processManifest.doLast {
            //渠道与配置名
            String variantName = variant.name.capitalize()

            //要替换的manifest文件
            def manifestFile = "${projectDir}${File.separator}build${File.separator}intermediates${File.separator}merged_manifests${File.separator}${variantName}${File.separator}AndroidManifest.xml"

            //源文件
            def srcManifact = "${projectDir}${File.separator}configs${File.separator}${variant.productFlavors[0].name}.xml"
            println "src: $srcManifact"

            //通过源文件内容替换
            def updatedContent = new File(srcManifact).getText('UTF-8')
            new File(manifestFile).write(updatedContent, 'UTF-8')
        }
    }
    ... ...
}

4.3、选择

选择第二种方式,因为第一种方式每次都需要传参或者改gradle源码及其不方便。第二种方式实现了自动化。

五、参数打包和代码中使用

5.1、在gradle中多渠道打包时配置BuildConfig

    productFlavors {
        OTT {
            dimension "default"
            buildConfigField "String", "FLAVORS_TYPE", '"OTT"'
        }
        OTT_DVB {
            dimension "default"
            buildConfigField "String", "FLAVORS_TYPE", '"OTT_DVB"'
        }
    }

5.2、设置默认参数时配置BuildConfig

1、app/gradle 配置

android {
    defaultConfig {
        ....
        buildConfigField "String", "FLAVORS_TYPE ", "\"${getTinkerIdValue()}\""
    }
}

//如果没有参数,就使用 1.0.0_base 作为名字
def getTinkerIdValue() {
    return hasProperty("FLAVORS_TYPE") ? FLAVORS_TYPE : "OTT1"
}

2、打包命令传参

gradlew assembleRelease -PFLAVORS_TYPE=OTT

5.3、java文件中使用

// BuildConfig 一定要导入 当前工程包名的,没有的话 先build一次
((TextView)findViewById(R.id.textView)).setText(BuildConfig.FLAVORS_TYPE);

结束语

以上就是本次分享的gradle 中定制化编译,以及相关设置的实例。最后惯例给大家推介一下我们的技术工作号,欢迎大家来交流技术问题,谢谢!

在这里插入图片描述

发布了61 篇原创文章 · 获赞 45 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/twk121109281/article/details/101353291