自定义gradle插件实现不同版本app的听云配置文件

Posted 安卓小小鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义gradle插件实现不同版本app的听云配置文件相关的知识,希望对你有一定的参考价值。

目录

问题由来

在做项目的时候,需要接入听云监测系统,因为我们的app分为 debug->preRelease->release 版本。这样的话,需要再在三个不同的版本平台同时接入。
不过听云的接入有一点比较坑的地方是需要配置tingyun.properties文件再app目录,
每次手动去新建肯定是不合适的,自然而然的就想到了gradle打包脚本,不过一开始是写在gradle.properties文件里的,具体代码如下

File TingyunProperties = new File("$project.projectDir.absolutePath/tingyun.properties")
            TingyunProperties.createNewFile()
        //gradle build package name
        android.applicationVariants.all  variant ->
        variant.productFlavors.each  flavor ->
            def variantSuffix = variant.name.capitalize()
            def generateResourcesTask = project.tasks.getByName("compile$variantSuffixSources")
            def generatePropertiesTask = task("TingyunGenerateProperties$variantSuffix") 
                doLast 
                    Properties properties = new Properties()
                    properties.load(TingyunProperties.newDataInputStream())
                    properties.setProperty("authKey", "")
                    properties.setProperty("appKey", flavor.manifestPlaceholders.tingyunAppToken)
                    properties.setProperty("mapping_file_auto_upload", "true")
                    properties.store(TingyunProperties.newWriter(), null)
                
            
            generateResourcesTask.dependsOn generatePropertiesTask
        

这就导致了一个问题,日常开发每次打包都会新建TingyunProperties的文件,次次提交都更改,有时候还会冲突,就会很烦,日常开发过程中其实并不需要我们去建立这个文件,只有在需要的时候新建一下就行了,于是就考虑到了自定义gradle插件来解决这个问题

自定义gradle插件流程

这个网上教程很多,我就不细讲了,可以参考 https://www.jianshu.com/p/0b7c141a5b75
这里主要讲一下需要注意的点和遇到的坑

productFlavor的获取

由于我们需要用到 productFlavor 这个属性去获取版本的名字,比如debug,所以在我们gradle插件的build.gradle 需要引入‘com.android.tools.build:gradle:3.6.3’
具体代码如下:

apply plugin: 'groovy'
apply plugin: 'maven'
dependencies 
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.tools.build:gradle:3.6.3'
    implementation gradleApi()

/**
 * 上传本地marven
 */
apply plugin: 'maven-publish'
publishing
    publications
        //这个名字任意取
        tingyun(MavenPublication)
            from  components.java
            groupId 'com.derek'
            artifactId 'tingyun'
            version '1.0.0'
        
    

plugin代码

package com.example.tingyunplugin
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
import com.android.builder.model.ProductFlavor
import org.gradle.api.Plugin
import org.gradle.api.Project

class tingyunPlugin implements Plugin<Project> 
    @Override
    void apply(Project project) 
        project.afterEvaluate 
            AppExtension android = project.extensions.android
            android.applicationVariants.all  ApplicationVariant variant  ->
                variant.productFlavors.each  ProductFlavor flavor ->
                    def variantSuffix = variant.name.capitalize()
                    //创建一个Task任务去处理听云
                    TingyunTask tingyunTask = project.tasks.create("createTingyunProperties$variantSuffix", TingyunTask)
                    tingyunTask.flavor = flavor
                
            

        


    

Task代码

package com.example.tingyunplugin
import com.android.builder.model.ProductFlavor
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class TingyunTask extends DefaultTask 
    ProductFlavor flavor
    TingyunTask()
        group = "tingyun"
    
    @TaskAction
    def run() 
        File TingyunProperties = new File("$project.projectDir.absolutePath/tingyun.properties")
        TingyunProperties.createNewFile()
        Properties properties = new Properties()
        properties.load(TingyunProperties.newDataInputStream())
        properties.setProperty("authKey", "")
        properties.setProperty("appKey", flavor.manifestPlaceholders.tingyunAppToken)
        properties.setProperty("mapping_file_auto_upload", "true")
        properties.store(TingyunProperties.newWriter(), null)
    


解释一下代码 :

TingyunTask()
        group = "tingyun"
    

这个代码是给我们的gradle任务分组,在AS中,我们可以看到很多的task,如图所示

那么,这个方法的作用就是给任务分组,如上图的tingyun

要想使用这个插件一定要将该插件上传到仓库

当我们写完自定义插件之后,不是直接引用一下就可以直接用了,一定要上传到(本地)仓库。
上传本地仓库(远程仓库一样)的gradle配置在gradle插件 的build.gradle中,代码如下

apply plugin: 'maven-publish'
publishing
    publications
        //这个名字任意取
        tingyun(MavenPublication)//tingyun的名字任意
            from  components.java //表示我们要将源代码打进jar包
            groupId 'com.derek'
            artifactId 'tingyun'
            version '1.0.0'
        
    

当搞定这个之后,我们就可以在gradle的任务栏中看到这个发布按钮了

点击publishToMavenLocal就可以发布到我们自己电脑的本地仓库了,Mac的地址在
/用户/用户名/.m2 目录下,如图

至此,就大功告成了,只需要在我们的工程目录下 repositories 中添加 mavenLocal()
dependencies 中添加 classpath ‘com.derek:tingyun:1.0.0’ 即可
具体代码如下

buildscript 
    repositories 
       .....
        mavenLocal()
        
    

    dependencies 
        .......//忽略的代码
        classpath 'com.derek:tingyun:1.0.0

在app的build gradle中引入即可,如图

至此,我们再gradle任务栏就可以看到我们的任务了,可以根据需要,来创建不同的properties文件了

Unable to load class 'com.xxxx.plugin


遇到这个问题一开始也很蒙,以为是网络问题或者是AS问题,但是本地仓库那里有网络问题啊,一度怀疑AS ,重启无效。
进入/用户/用户名/.m2 目录下查看.jar 文件 只有600多字节,解压缩一看,里面没有class文件,怪不得引用不到。
如果你也遇到这个问题,你需要查看一下自己的task任务或者plugin插件,是不是groovy文件,查看方式就是 右击你的groovy文件,选择Refactor->renameFile.看看是不是以groovy结尾的


如果是的话就没问题,为什么这么说,我就是因为有一个groovy文件不知道是bug还是什么原因,没有.groovy结尾,同时你要是手动添加的话,还报错,所以如果你有这个问题的话,可以这么排查一下,解决方法就是复制代码,然后删掉源文件,新建新的groovy文件

当处理完这些,你就可以再gradle任务栏执行一下build任务

如果在build文件夹下看到对应的编译文件,就说明没问题了。打包重新上传即可

另外还有一点就是要注意的是,groovy不会自动给你写包名,这个也会导致.class文件编译不出来,这个也是要注意的。

记录一下。

以上是关于自定义gradle插件实现不同版本app的听云配置文件的主要内容,如果未能解决你的问题,请参考以下文章

Android Gradle 插件自定义 Gradle 插件模块 ② ( 在模块中定义插件 | 引入自定义 Gradle 插件模块 | 配置 Gradle 插件上传选项 | 配置分组名称版本号 )

Android Gradle 插件自定义 Gradle 插件模块 ⑤ ( 完整总结 ) ★★★

Android Gradle 插件Gradle 自定义 Plugin 插件 ② ( buildSrc 目录中实现 Gradle 插件 | 实现 Gradle 插件代码 | 模块引入插件并编译 )

Android Gradle 插件Gradle 自定义 Plugin 插件 ④ ( 为自定义 Gradle 插件的扩展配置扩展 | 在自定义插件中获取扩展属性 )

Android gradle 自定义配置

Android gradle 自定义配置