Gradle核心(四):Gradle插件

博客主頁java

這篇主要講Java Gradle插件、Android Gradle插件以及自定義插件等android

Gradle插件

Gradle內置了不少插件,其中Android Gradle插件就是基於內置的Java插件實現的。segmentfault

應用一個插件

插件的應用都是經過Projectapply方法完成的,而插件又分爲二進制插件和腳本插件。api

應用插件方法

二進制插件就是實現了org.gradle.api.Plugin接口的插件,能夠有plugin id,如java插件。二進制插件通常都是打包在一個jar獨立發佈服務器

// 'java'就是Java插件的plugin id,是惟一的
// 它對應獲得類型是org.gradle.api.plugins.JavaPlugin
apply plugin: 'java'

// 也能夠經過該類型應用這個插件,包org.gradle.api.plugins是默認導入的,能夠去掉
apply plugin: JavaPlugin

應用腳本插件其實就是把這個腳本加載進來,與二進制插件不一樣的是,腳本插件使用from關鍵字,後面跟一個腳本文件,能夠是本地的,也能夠是網絡,若是是網絡要使用HTTP URL。
更重要的是,腳本文件是模塊化的基礎。網絡

// 在build.gradle文件中引用腳本文件
apply from: 'config/project.config.gradle'

// project.config.gradle腳本文件
ext {
    // android sdk version
    // 使用以下:
    // def versions = rootProject.ext.versions
    // compileSdkVersion versions.compileSdkVersion
    // buildToolsVersion versions.buildToolsVersion
    versions = [
            compileSdkVersion: 26,
            minSdkVersion    : 19,
            targetSdkVersion : 26,
            versionCode      : 182,
            versionName      : '1.8.2',
    ]

    // dependencies
    // 使用以下:
    // def dependencies = rootProject.ext.dependencies
    // compile dependencies.support.design
    dependencies = [
            support     : [
                    appcompat : "com.android.support:appcompat-v7:26.1.0",
                    constraint: "com.android.support.constraint:constraint-layout:1.1.3",
                    design    : "com.android.support:design:26.1.0"
            ],
            gson        : "com.google.code.gson:gson:2.8.5"
    ]
}

Project中的apply有3個重載方法能夠應用插件app

void apply(Closure closure);
void apply(Action<? super ObjectConfigurationAction> action);
void apply(Map<String, ?> options);

應用第三方發佈的插件

第三方發佈的二進制插件,須要在buildscript {}中配置classpath才能使用,跟Gradle提供的內置插件不同。而Android Gradle插件就是第三方插件,須要配置,若是不配置,就會提示找不到這個插件。maven

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        // 配置插件
        classpath 'com.android.tools.build:gradle:3.0.1'
    }
}

配置好第三方插件後,就能夠應用插件了ide

apply plugin: 'com.android.application'
Grade社區提供了好多插件,能夠在下面地址找到.
https://plugins.gradle.org/

自定義插件

咱們能夠根據本身的實際業務自定義一些插件,來輔助項目構建。模塊化

自定義插件須要實現Plugin接口,這個接口只有apply一個方法,該方法配置階段調用,咱們能夠在該方法中建立任務,建立方法等。

僅本身項目使用自定義插件

若是自定義的插件只在本身的項目使用,能夠簡單的定義在build腳本文件裏

// build.gradle文件中

// 應用自定義的插件
apply plugin: CustomPlugin

// 
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        println "我是自定義插件."
        project.task('customPluginTask') {
            println "我是自定義任務.."
            doLast {
                println "這是一個經過自定義插件方式建立任務."
            }
        }
    }
}

或者新建buildSrc,目錄結構以下:

只須要在build.gradle腳本中應用就OK了

// 注意包名須要加上
apply plugin: com.example.gradle.plugins.MyCustomPlugin

自定義插件供其餘項目使用

可是若是想開發一個獨立的插件供其餘的項目使用,怎麼作呢?這須要單首創建一個Groovy工程開發自定義插件:

首先按照下如圖創建groovy目錄後,自定義一個MyPlugin插件類,包名能夠任意,如:com.custom.gradle.plugins

而後實現插件類,自定義插件MyPlugin,實現Plugin接口

package com.custom.gradle.plugins

import org.gradle.api.Plugin
import org.gradle.api.Project
// 自定義插件,須要實現Plugin接口
class MyPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('myCustomPluginTask') {
            doLast {
                println "這個在myPlugin中自定義插件的方式建立任務."
            }
        }
    }

}

而每一個插件都有一個惟一的plugin id,須要咱們自定義。
Gradle是經過META-INF裏的properties文件來查找對應插件實現類的。
我這裏定義的plugin id是com.custom.plugin.myplugin,而後在src/main/resources/META-INF/gradle-plugins/目錄中新建一個名字爲plugin id的properties文件,如com.custom.plugin.myplugin.properties,文件內容以下:

// key爲implementation-class,value就是自定義的插件實現類
implementation-class=com.custom.gradle.plugins.MyPlugin

在build.gradle文件中配置自定義插件所需的依賴:

// 應用groovy插件
apply plugin: 'groovy'

dependencies {
    implementation gradleApi()
    implementation localGroovy()
    compileOnly 'com.android.tools.build:gradle:3.4.2'
}

repositories {
    mavenCentral()
}

sourceSets {
    main {
        groovy {
            srcDir 'src/main/groovy'
        }

        resources {
            srcDir 'src/main/resources'
        }
    }
}

打包到本地的Maven倉庫

打包到本地的Maven倉庫(僅僅爲了測試自定義插件),最終打包上傳到遠程Maven倉庫

// 應用maven插件
apply plugin: 'maven'

//配置分組group和版本version
group = 'com.custom.plugin'
version = '1.0.1'

uploadArchives {
    repositories {
        mavenDeployer {
            //提交到遠程服務器:
            // repository(url: "http://www.xxx.com/repos") {
            //    authentication(userName: "admin", password: "admin")
            // }
            //本地的Maven地址設置爲D:/repos
            repository(url: uri('D:/repos'))
        }
    }
}

執行gradlew uploadArchives命令後,就是上傳到本地的repos倉庫,以下圖所示:

其餘項目使用自定義插件

在Root Project中的build.gradle文件中配置

buildscript {
    repositories {
        maven { // 配置自定義插件本地Maven倉庫地址
            url uri('D:/repos')
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.2'
        // 配置自定義的插件 group:com.custom.plugin, name:myPlugin,version:1.0.1
        // 簡寫格式:  group:name:version
        classpath 'com.custom.plugin:myPlugin:1.0.1'

       // 標準的寫法,上面簡寫格式,使用 冒號 分隔group,name,version
       // classpath group: 'com.custom.plugin', name: 'myPlugin', version: '1.0.2'
    }
}

在Sub Project中build.gradle文件中應用plugin id

// com.custom.plugin.myplugin是plugin id
// plugin id爲resources/META-INF/gradle-plugins/com.custom.plugin.myplugin.properties文件名
apply plugin: 'com.custom.plugin.myplugin'

Android Gradle插件

Android插件就是Gradle的一個第三方插件,基於Gradle構建的。

Android Gradle插件根據Android工程屬性分3類:

  1. App應用工程,可生成一個APK應用,插件id: com.android.application
  2. Library庫工程,可生成AAR包,包含資源信息,插件id: com.android.library
  3. Test測試工程,插件id: com.android.test

應用Android Gradle插件

Android Gradle是託管在jcenter上,在根工程的build.gradle中要先配置依賴classpath

// 根工程build.gradle
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
    }
}

配置好後,在子工程的build.gradle就能夠應用插件了,其實android {}是Android插件提供的一個擴展類型。

// 子工程build.gradle
apply plugin: 'com.android.application'

android {
  compileSdkVersion 23
}

Android Gradle工程

Android Gradle插件繼承Java插件,須要在settings.gradle中配置子工程。

Android Gradle工程的配置,都是在android {},這是惟一的一個入口。能夠對Android Gradle工程自定義配置,它的具體實現是com.android.build.gradle.AppExtension,是Project的一個擴展。

compileSdkVersion

配置Android SDK的版本,該配置的原型是:

public void compileSdkVersion(int apiLevel) {
   compileSdkVersion("android-" + apiLevel);
}

除了上面方法外,還提供了set方法,能夠當作android的一個屬性使用

android.compileSdkVersion = 23

buildToolsVersion

buildToolsVersion "23.0.1" 表示Android構建工具版本。能夠直接經過 buildToolsVersion 方法賦值,也能夠經過android.buildToolsVersion 這個屬性賦值。

defaultConfig

defaultConfig是默認的配置,它是一個ProductFlavor。ProductFlavor容許根據不一樣的狀況生成多個不一樣的APK包,好比多渠道打包。若是不針對自定義的ProductFlavor單獨配置,會爲這個ProductFlavor使用默認的defaultConfig配置。

android{
   defaultConfig {
        // 是一個屬性,指定包名,沒有指定從AndroidManifest.xml文件中讀取
        applicationId "com.kerwin"
        // 是一個方法,配置最低支持的Android系統版本
        minSdkVersion 19
        // 是一個方法,配置基於哪一個Android版本開發,沒有配置從AndroidManifest.xml文件中讀取
        targetSdkVersion 26
        // 是一個屬性,配置App應用的內部版本號,通常控制App升級,建議配置
        versionCode 100
        // 是一個屬性,配置App應用的版本名稱,可查看App是哪個版本,外部使用
        versionName "1.0.0"

       //是一個屬性,默認是:applicationId  + ".test"
       testApplicationId "com.kerwin.test"
       // 配置單元測試時使用的Runner,默認:android.test.InstrumentationTestRunner
       testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }
}

buildTypes

buildTypes是一個NamedDomainObjectContainer類型,是一個域對象。能夠在buildTypes {} 中增長多個須要構建的類型,如:release,debug
release就是Gradle自動建立的一個對應的BuildType

buildTypes {
    release {
         // 是否爲該構建類型啓用混淆,true:啓用
         minifyEnabled true
         // 當啓動混淆時,所使用的proguard的配置文件,proguardFiles 接受可變參數
         // getDefaultProguardFile方法 獲取Android SDK目錄下默認的配置文件
         // 路徑:android-sdk\tools\proguard\proguard-android.txt
         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard/proguard-rules.pro'
   }
}

signingConfigs配置簽名信息

配置簽名信息,對生成的APK簽名。

android{
       // 是一個方法,其類型NamedDomainObjectContainer,debug 和 release 定義的是一個SigningConfig
       // 一個SigningConfig就是一個簽名配置
       signingConfigs {
            def signingConfig = rootProject.ext.signingConfigs
            def debugSigningConfig = signingConfig.debug
            // debug配置,通常debug模式是已經配置好的。debug證書位於:${HOME}\.android\debug.keystore
            debug {
                // 簽名文件
                storeFile file(debugSigningConfig.storeFile)
                // 簽名證書文件密碼
                storePassword debugSigningConfig.storePassword
                // 簽名證書中密鑰別名
                keyAlias debugSigningConfig.keyAlias
                // 簽名證書中密鑰的密碼
                keyPassword debugSigningConfig.keyPassword
            }

            // release 配置
            release {
                storeFile file(jenkinsProperties['KEY_STORE'])
                storePassword jenkinsProperties['KEY_STOREPWD']
                keyAlias jenkinsProperties['KEY_ALIAS']
                keyPassword jenkinsProperties['KEY_ALIASPWD']
            }
        }
  }

能夠在defaultConfig中默認的簽名配置,也能夠在構建類型分別配置簽名信息。

android {
   buildTypes {
       release {
           // signingConfigs是Android對象實例的一個屬性,對應是getSigningConfigs(),release是建立的簽名配置名稱
           signingConfig signingConfigs.release
       }
      
       debug {
           signingConfig signingConfigs.debug
       }
   }
}

buildTypes構建類型

buildTypes也是Android的一個方法,接受參數是域對象NamedDomainObjectContainer,每添加一個都是BuildType類型,如debug

android {
   buildTypes {
       debug {
           // 是一個屬性,配置基於applicationId 的後綴。配置後,debug版本包名爲applicationId.debug
           applicationIdSuffix ".debug"
           // 是一個屬性,配置是否生成一個可供調試的apk
           debuggable true
           // 是一個屬性,配置是否生成一個可供調試JNI代碼的apk
           jniDebuggable true
           // 是一個屬性,是否開啓混淆
           minifyEnabled true
           // 是一個屬性,是否啓用自動拆分多個dex的功能
           multiDexEnabled true
           // 是一個屬性,配置簽名配置
           signingConfig signingConfigs.release
           // 是一個方法,配置多個混淆文件
           proguardFiles getDefaultProguardFile('proguard-android.txt'),
                        'proguard/proguard-rules.pro'
           // 是一個屬性,配置是否自動清理未使用的資源,默認false
           shrinkResources true
           // 是一個屬性,zipalign是Android提供的一個整理優化apk文件工具。
           // 能夠提升應用運行效率,更快讀寫apk中資源,下降內存使用
           zipAlignEnabled true
       }
   }
}

若是個人文章對您有幫助,不妨點個贊鼓勵一下(^_^)

相關文章
相關標籤/搜索