Android Gradle 外掛開發指南
作為Android開發者,你可能見過無數個 apply plugin:plugin_name
, plugin_name
對應著相應的外掛。
例如:
apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
com.android.application
就對應著可以一個構建 APK 的Gradle外掛,而 com.android.library
則對應著一個構建 android library
的外掛。
Gradle外掛開發支援 Java、Groovy、Scala
三種語言開發, Groovy
用於實現與 Gradle 構建生命週期(如 task 的依賴)有關的邏輯, Java
用於核心邏輯,表現為 Groovy 呼叫 Java 的程式碼。
外掛的打包方式
Gradle的外掛有三種打包方式,主要是按照複雜程度和可見性來劃分:
型別 | 說明 |
---|---|
Build script | 把外掛寫在 build.gradle 檔案中,一般用於簡單的邏輯,只在該 build.gradle 檔案中可見 |
buildSrc 專案 | 將外掛原始碼放在 rootProjectDir/buildSrc/src/main/groovy 中,只對該專案中可見,適用於邏輯較為複雜,但又不需要外部可見的外掛,可以參見 |
獨立專案 | 一個獨立的 Groovy 和 Java 專案,可以把這個專案打包成 Jar 檔案包,一個 Jar 檔案包還可以包含多個外掛入口,將檔案包釋出到託管平臺上,供其他人使用。本文將著重介紹此類。 |
接下來我將從Build script和獨立專案詳細介紹。
Buid script
把外掛寫在 build.gradle
檔案中,這種是最簡單的外掛開發方式。
下邊舉個例子:
build.gradle//檔名
class GreetingPluginExtension{
String message = "Hello from GreetingPlugin"
}
class GreetingPlugin implements Plugin<Project>{
@Override
void apply(Project project){
def extension = project.extensions.create('greeting',GreetingPluginExtension)
project.task('hello'){
doLast {
println extension.message
}
}
}
}
apply plugin: GreetingPlugin //應用外掛,這樣外掛才能在gradle構建過程中生效。
在 build.gradle
同級目錄中,在命令列執行 gradle greeting
。則會輸出以下內容:
Hello from GreetingPlugin
這個外掛建立了一個名為 hello
的task,並在task中列印了 GreetingPluginExtension#message
的內容。
create的第一個引數 greeting
是我們自定義配置的DSL名字,第二個引數是引數類的名字。
通過 greeting
這個DSL這個名字,我們可以任意的改變引數類中相應欄位的值。這樣就帶來了很大的便利。
比如我們將Android工程的app目錄中經常見到 build.gradle
中會有
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
applicationId "com.chenenyu.plugintest"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
而這些就是名為android DSL的動態引數配置。
同樣,我們把剛才寫的 build.gradle
中新增新的內容,如下:
class GreetingPluginExtension{
String message = "Hello from GreetingPlugin"
}
class GreetingPlugin implements Plugin<Project>{
@Override
void apply(Project project){
def extension = project.extensions.create('greeting',GreetingPluginExtension)
project.task('hello'){
doLast {
println extension.message
}
}
}
}
apply plugin:GreetingPlugin
greeting{
message="I am dynamic message"
}
重新執行 gradle hello
,則會看到以下內容:
I am dynamic message
在本小節介紹了Gradle外掛的基本開發,通過繼承 org.gradle.api.Plugin
即可簡單快速的實現。同時我們通過 project.extensions.create
可以實現動態傳參。只需要定義DSL名字和定義相應的Class,並且在DSL作用域中重新賦值。
在Gradle外掛開發中,所有的外掛都要繼承org.gradle.api.Plugin介面,並且需要重寫void apply(Project project) 方法,這個方法將會傳入使用這個外掛的 project 的例項,這是一個重要的 context。
獨立專案外掛
獨立的專案可以釋出到本地或者jcenter倉庫中,這樣就會很方便第三方整合。
通常我們可以在 build.gradle
中來改變APK最終輸出的名字。我們換個套路,把這個功能放在外掛中來完成。同時將該外掛釋出到本地倉庫,同時在第三方APP中應用該外掛。
001 建立專案
在 Android Studio 中新建 Java Library module “plugin”。
002 修改 build.gradle 檔案
apply plugin: 'groovy'
apply plugin: 'maven'
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile gradleApi()
}
//publish to local directory
def versionName = "1.0.0"
group "com.demon.plugin"
version versionName
uploadArchives{ //當前專案可以釋出到本地資料夾中
repositories {
mavenDeployer {
repository(url: uri('./repo')) //定義本地maven倉庫的地址
}
}
}
003 修改專案資料夾
src/main 專案檔案下:
● 移除 java 資料夾,因為在這個專案中用不到 java 程式碼
● 新增 groovy 資料夾,主要的程式碼檔案放在這裡
● 新增 resources 資料夾,存放用於標識 gradle 外掛的 meta-data
004 建立對應檔案
├── build.gradle
└── src
└── main
├── groovy
│ └── com
│ └── demon
│ └── plugin
│ ├── ApkChangeNamePlugin.groovy
│
└── resources
└── META-INF
└── gradle-plugins
└── apk_change_name.properties
ApkChangeNamePlugin.groovy檔案內容如下:
package com.demon.plugin
import org.gradle.api.Project
import org.gradle.api.Plugin
class ApkChangeNamePlugin implements Plugin<Project>{
@Override
void apply(Project project) {
if(!project.android){
throw new IllegalStateException('Must apply \'com.android.application\' or \'com.android.library\' first!');
}
project.android.applicationVariants.all{
variant ->
variant.outputs.all{
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
}
}
apk_change_name.properties
檔案內容如下:
implementation-class=com.demon.plugin.ApkChangeNamePlugin //指定實現類
注意:
● groovy資料夾中的類,一定要修改成 .groovy 字尾,IDE才會正常識別。
● resources/META-INF/gradle-plugins 這個資料夾結構是強制要求的,否則不能識別成外掛。
● apk_change_name.properties
中 apk_change_name
為外掛名
005 釋出外掛到本地目錄中
執行如下命令即可
gradle uploadArchives
則會在 build.gradle
的同級目中生成repo目錄,裡邊的內容如下圖:
Picture
006 在第三方APP中使用外掛
在專案的 buildscript 新增外掛作為 classpath
buildscript {
repositories {
maven{
url '/Users/demon.li/workspace/GradlePlugin/repo/'
}
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "com.demon.plugin:plugin:1.0.0"
}
}
在 app module
中使用外掛:
apply plugin: 'apk-change-name'
在最終的apk構建後會根據variant名字和版本的不同而輸出不同名稱的apk。
例如最終生成:
debug-1.0.apk
release-1.0.apk
總結
就實現了在Android專案中壓縮 .png
圖片的外掛。
我們在這裡也用到了 Groovy
,如果想深入Gradle外掛開發的同學可以學習一下Groovy語言的精妙。
Groovy也是藉助於Java虛擬機器執行的,Java虛擬機器規範定義了位元組碼的規範。比如kotlin和Scala都是執行在Java虛擬機器中的。
原文釋出時間為:2018-10-29
本文作者:我是吸血鬼
本文來自雲棲社群合作伙伴“ ofollow,noindex">安卓巴士Android開發者門戶 ”,瞭解相關資訊可以關注“ 安卓巴士Android開發者門戶 ”。