Gradle plugin自定義

背景

最近組里gradle大神帶大家一起飛,lz也趁機(jī)學(xué)習(xí)一下Gradle相關(guān)的知識。我們工程中的gradle的腳本幾乎是我所見過的最復(fù)雜的工程(另一個是Tinker),里面有自定義的plugin,也有自己執(zhí)行的一些腳本,如lint,時間監(jiān)聽,findbugs,Checkstyle等,也使用gradle transform api 動態(tài)插樁。lz 作為小白,默默從自定義gradle plugin 開始。

先看gradle的工程結(jié)構(gòu)圖

Paste_Image.png

主工程app, submodule helloplugin

helloplugin 通過新建

Paste_Image.png
Paste_Image.png

lets go

helloplugin 的gradle配置如下

apply plugin: 'groovy'
//添加maven plugin, 用于發(fā)布我們的jar
apply plugin: 'maven'


dependencies {
    compile gradleApi()
    compile localGroovy()
}

repositories {
    mavenCentral()
}


//設(shè)置maven deployer
uploadArchives {
    repositories {
        mavenDeployer {
            //設(shè)置插件的GAV參數(shù)
            pom.groupId = 'plugin'
            pom.artifactId = 'helloplugin'
            pom.version = 1.2
            //文件發(fā)布到下面目錄
            repository(url: uri('../release'))
        }
    }
}

其中uploadArchives用于上傳plugin到本地release文件夾下(實際使用一般 是私有maven倉庫)。 其實看過我前面IntelliJ IDEA spring mvc +mybatis 環(huán)境搭建服務(wù)器 http://www.itdecent.cn/p/c7060f84bf5c 等系列的童鞋不會陌生groupId、artifactId、version 目的是相當(dāng)于配置一個工程唯一id。

新建groovy和resources文件夾

Paste_Image.png

主插件類HelloPlugin.groovy

package plugin

import org.gradle.api.Plugin
import org.gradle.api.Project

public class HelloPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {

        project.extensions.create('apkdistconf', ApkDistExtension);
        project.task('hellotask') << {
            println "hello, this is test task!"
        }
        project.afterEvaluate {

            //只可以在 android application 或者 android lib 項目中使用
            if (!project.android) {
                throw new IllegalStateException('Must apply \'com.android.application\' or \'com.android.library\' first!')
            }

            //配置不能為空
            if (project.apkdistconf.nameMap == null || project.apkdistconf.destDir == null) {
                project.logger.info('Apkdist conf should be set!')
                return
            }

            Closure nameMap = project['apkdistconf'].nameMap
            String destDir = project['apkdistconf'].destDir

            //枚舉每一個 build variant,生成的apk放入如下路徑和文件名
            project.android.applicationVariants.all { variant ->
                variant.outputs.each { output ->

                    File file = output.outputFile
                    print("dir " + destDir + " " + file.getName())
                    output.outputFile = new File(destDir, nameMap(file.getName()))
                }
            }
        }

    }

}

需要繼承 Plugin<Project> ,當(dāng)主gradle使用//使用helloplugin
apply plugin: 'helloplugin'時,就會調(diào)用apply方法。

ApkDistExtension.groovy擴(kuò)展的屬性

package plugin

class ApkDistExtension {
    Closure nameMap = null;
    String destDir = null;
}

groovy語法,默認(rèn)生成get和set方法。

配置指向插件的主類HelloPlugin

Paste_Image.png
implementation-class=plugin.HelloPlugin

注意路徑為plugin.HelloPlugin 全包名 + 類名

編譯

此時會發(fā)現(xiàn)

Paste_Image.png

運行uploadArchives task就可以將其打包到本地了。
此時,如下:

Paste_Image.png

使用

Paste_Image.png
import plugin.HelloWorldTask

apply plugin: 'com.android.application'
//使用helloplugin
apply plugin: 'helloplugin'


buildscript {
    repositories {
        maven {
            //cooker-plugin 所在的倉庫
            //這里是發(fā)布在本地文件夾了
            url uri('../release')
        }
    }
    dependencies {
        //引入helloplugin
        classpath 'plugin:helloplugin:1.2'
    }

    tasks.withType(JavaCompile) {
        sourceCompatibility = JavaVersion.VERSION_1_7
        targetCompatibility = JavaVersion.VERSION_1_7
    }
}

task hello1(type:HelloWorldTask){
    message ="I am a programmer"
}


apkdistconf {
    nameMap { name ->
        println 'hdasd, ' + name
        return name
    }
    destDir "$project.path"
}



android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.nothing.plugindemo"
        minSdkVersion 11
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}



dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:25.1.1'
    compile project(':helloplugin')
}

type:HelloWorldTask是helloplugin里面自定義的一個task不影響使用,可以去掉或參考我上傳的。
正常運行即可。
這里有幾點說明下,其他groovy還是和其他腳本很相似的,閉包也與lamda表達(dá)式類似。 destDir "$project.path"相當(dāng)于 setDestDir("$project.path"), $用戶變量,與其他腳本類似。

遇到的問題

第一個問題,找不到,這里需要分析找不到ext的原因: 本來未定義或其他,這里是我自己已經(jīng)upload了一次之后,沒有upload新的gradle plugin,自己挖的坑含著淚也要跳下去。

Error:(25, 0) Could not find method sa() for arguments [build_2x9mdgfer2n7ji1nsjr5g8ki6$_run_closure1@32b044f8] on project ':app' of type org.gradle.api.Project.
<a href="openFile:XXX/pluginTest/app/build.gradle">Open File</a>

報的錯誤


Paste_Image.png

在主gradle 添加如下配置:

buildscript {
    tasks.withType(JavaCompile) {
        sourceCompatibility = JavaVersion.VERSION_1_7
        targetCompatibility = JavaVersion.VERSION_1_7
    }
}

參考

  1. http://www.itdecent.cn/p/873eaee38cc1
  2. http://www.itdecent.cn/p/bcaf9a269d96
  3. http://kvh.io/cn/embrace-android-studio-gradle-plugin.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 這篇文章講給大家?guī)韌radle打包系列中的高級用法-自己動手編寫gradle插件。我們平常在做安卓開發(fā)時,都會在...
    呆萌狗和求疵喵閱讀 16,329評論 22 80
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評論 25 709
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,261評論 6 342
  • 今天這3個故事都是關(guān)于人在面對困難的時候,選擇哪種解決問題的方式往往是由你的處理問題的態(tài)度,你的心理承受...
    遇上緣閱讀 271評論 0 0

友情鏈接更多精彩內(nèi)容