一、前言
現(xiàn)在大家基本都用Android Studio(AS)開發(fā)安卓,AS是使用Gradle構(gòu)建項(xiàng)目,打開工程的build.gradle文件,在頭部能看到apply plugin: 'com.android.application',或者apply plugin: 'com.android.library',如果引入了Tinker熱修復(fù),還看到apply plugin: 'com.tencent.tinker.patch',那apply plugin是什么,起什么作用,如何定義及使用。
二、Gradle Plugin的作用
2.1 Gradle 與Gradle Plugin
Gradle:Gradle:Gradle是一款幫助開發(fā)人員更快更好的編譯、自動(dòng)化運(yùn)行和分發(fā)軟件的工具。Gradle具有無(wú)與倫比的通用性,可以編譯Java、C++,Python或者任何其他你使用的語(yǔ)言。Gradle官網(wǎng)鏈接。
Gradle Plugin:Gradle的插件,編譯Android App的插件叫做Android Plugin for Gradle。 Android Studio的編譯系統(tǒng)使用的就是Gradle,Android Plugin for Gradle增加了編譯Android APP所需要的特性。
Android Studio創(chuàng)建的APP工程中可以在工程(非子module)的build.gradle文件buildscript里配置依賴的插件版本。如下:
buildscript {
repositories {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
}
}
2.2 Gradle Plugin的作用
- 模塊化構(gòu)建腳本的功能
- 公共的功能可以抽取出來成為插件,可以供多個(gè) build.gradle 使用,增加復(fù)用性
- 通過插件修改編譯后的class文件,對(duì)于關(guān)鍵節(jié)點(diǎn)的插樁做性能監(jiān)控,修改第三方依賴等
三、自定義一個(gè)Gradle Plugin
3.1 創(chuàng)建Gradle Plugin工程
1、在項(xiàng)目工程中,新建一個(gè)命名為buildSrc的Module,類型為Java Library,其他類型也行,創(chuàng)建后刪掉不必要的文件和目錄,只保留src和build.gradle即可。
2、將 main/src/java 修改為 main/src/groovy

3、創(chuàng)建MyPlugin類實(shí)現(xiàn)接口Plugin<Project>,并重寫apply方法。
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
System.out.println("start ")
System.out.println("hello my gradle plugin")
System.out.println("end")
}
}
4、在外部使用該插件
先Sync Project,然后在其他子工程的build.gradle中輸入關(guān)鍵字就能出現(xiàn)剛剛創(chuàng)建的plugin:
import com.siu.buildsrc.MyPlugin
apply plugin: 'com.android.application'
apply plugin: MyPlugin
5、執(zhí)行驗(yàn)證
在命令行中執(zhí)行打包命令:
gradlew build
Configure project :app
start
hello my gradle plugin
end
從日志,可以看到,在Configure app工程的階段,執(zhí)行了插件。
3.2 打包插件
上面新創(chuàng)建的插件的引用方式是直接引用了MyProject,可以跳轉(zhuǎn)到對(duì)應(yīng)的plugin文件定義,跟apply plugin: 'com.android.application'有些不同,那另外這種方式是怎么定義的呢。
Gradle plugin的引用方式可分為兩種:
- 一種是只能在本工程中使用的插件
- 另一種是可以將其打包發(fā)布出去使用的插件,引用其實(shí)是一個(gè)別名( Plugin ID )
上面創(chuàng)建的插件就是在本工程直接引用的,命名必須為buildSrc,而打包發(fā)布出去的對(duì)命名沒有要求。
要發(fā)布出去該怎么打包?
1、新建文件夾src/main/resources/META-INF/gradle-plugins,并在文件夾下創(chuàng)建文件:myplugin_alias.properties,
注意myplugin_alias是引用的別名(Plugin ID )。

2、文件內(nèi)容指向plugin文件
implementation-class=com.siu.buildsrc.MyPlugin
3、打包發(fā)布
在插件工程buildSrc的build.gradle文件中配置版本號(hào)和打包上傳目錄。
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
uploadArchives {
repositories {
mavenDeployer {
//提交到遠(yuǎn)程服務(wù)器:
// repository(url: "maven url") {
// authentication(userName: "xxx", password: "xxx")
// }
//本地的Maven地址設(shè)置為項(xiàng)目根目錄下的repositories
repository(url: uri('../repositories'))
pom.groupId = 'com.siu.buildSrc' //groupId,自行定義,一般是包名
pom.artifactId = 'buildSrc'//artifactId,自行定義
pom.version = '1.0.0' //插件版本號(hào)
}
}
}
然后在AS右側(cè)的Gradle菜單中找到對(duì)應(yīng)的task,先執(zhí)行雙擊執(zhí)行build,再執(zhí)行uploadArchives。

然后在剛配置的本地maven目錄repositories中能找到打包后的文件。

4、引用
先在工程總的build.gradle目錄下指定需要依賴的插件及版本
buildscript {
repositories {
google()
url uri('./repositories') //指定本地maven路徑
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.siu.buildsrc:customId:1.0.0'
}
}
然后在需要執(zhí)行插件的子工程的build.gradle中引用:
apply plugin: 'com.android.application'
apply plugin: 'myplugin_alias'
5、驗(yàn)證
gradlew build
Configure project :app
start
hello my gradle plugin
end
從日志,可以看到,在Configure app工程的階段,執(zhí)行了插件。
四、總結(jié)
本文總結(jié)了Gradle Plugin的作用及如何自定義Gradle Plugin,學(xué)習(xí)后對(duì)Gradle的打包流程有更多的了解,也知道了可以通過Plugin hook 編譯過程,在編譯前、中或后執(zhí)行一些特定的任務(wù),例如修改配置文件、修改class文件對(duì)關(guān)鍵節(jié)點(diǎn)進(jìn)行插樁,事實(shí)上,一些性能監(jiān)控sdk就是通過Plugin的方式對(duì)代碼插樁,然后做監(jiān)控性能,微信的Tinker也是使用插件(apply plugin: 'com.tencent.tinker.patch')打補(bǔ)丁包。