Gradle系列已完成,專一於Gradle,有以下幾篇文章html
依賴apply plugin: 'com.android.application'
就是依賴了安卓的應用程序插件.而後這個插件裏面有android擴展,在官方文檔裏面有詳細描述.可是,有時候不得不本身寫一個插件,方便與業務開展.好比我以爲美團的熱修復,在每一個方法前面插邏輯的話,確定得插樁,插樁就得本身寫插件.方便快捷.Gradle+ASM能夠插樁.有興趣的能夠去了解.java
demo地址: github.com/xfhy/Gradle…android
新建一個簡單的項目,而後建立一個buildSrc這個名字的module,這個module的名稱必須爲buildSrc.由於咱們建立的這個module是AS專門用來寫插件的,會自動參與編譯.建立好以後刪除Android那一堆東西,什麼java代碼,res,清單文件等.只剩下build.gradle和.gitignoregit
把build.gradle文件內容改爲github
repositories {
google()
jcenter()
}
apply {
plugin 'groovy'
plugin 'java-gradle-plugin'
}
dependencies {
implementation gradleApi()
implementation localGroovy()
implementation "commons-io:commons-io:2.6"
}
複製代碼
而後在main下面建立文件夾groovy,sync一下.沒啥問題的話,應該能編譯過.而後在groovy文件夾下面建立包名com.xfhy.plugin
,而後建立一個插件,名字叫CustomPlugin.groovyapi
package com.xfhy.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
class CustomPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.task('showCustomPlugin') {
doLast {
println('hello world plugin!')
}
}
}
}
複製代碼
我在這裏聲明瞭一個CustomPlugin插件,而後裏面建立了一個task名字叫showCustomPlugin,showCustomPlugin插件就只是簡單輸出一句話. 而後在app的build.gradle裏面引入這個插件bash
import com.xfhy.plugin.CustomPlugin
apply plugin: CustomPlugin
複製代碼
而後就能夠在命令行輸入gradlew showCustomPlugin
執行這個插件.而後就能夠在命令行看到輸出了.就這樣簡單的幾步,一個簡單的插件就寫完了,雖然只是簡單地打印了hello world.
.閉包
可是,咱們確定不會知足於只會輸出hello world的插件,咱們來作一個稍微有點用的插件.正如咱們日常在android{} 閉包裏面,咱們寫了不少次的app
compileSdkVersion Config.compileSdkVersion
buildToolsVersion Config.buildToolsVersion
....
複製代碼
那咱們就來作這樣一個插件,讀取這些配置信息的數據.首先在包名com.xfhy.plugin
下面建立AndroidExtension.groovy
,它是一個bean對象,用來保存信息的.定義以下:ide
package com.xfhy.plugin
class AndroidExtension {
String compileSdkVersion = ''
String buildToolsVersion = ''
String applicationId = ''
String minSdkVersion = ''
}
複製代碼
而後建立一個新的插件MyAndroidPlugin.groovy
package com.xfhy.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyAndroidPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
def extension = project.extensions.create('testExtension', AndroidExtension)
project.task('AndroidPlugin') {
doLast {
println("minSdkVersion = ${extension.minSdkVersion}")
println("applicationId = ${extension.applicationId}")
println("compileSdkVersion = ${extension.compileSdkVersion}")
println("buildToolsVersion = ${extension.buildToolsVersion}")
}
}
}
}
複製代碼
經過project.extensions.create
來獲取testExtension閉包中的內容,並經過反射將閉包中的內容轉成一個AndroidExtension對象.而後我建立了一個task去讀取它.
而後咱們在app下面的build.gradle中加入代碼:
testExtension {
minSdkVersion '22'
applicationId 'com.xfhy.gradledemo'
compileSdkVersion '29'
buildToolsVersion '29.0.2'
}
複製代碼
輸出以下:
minSdkVersion = 22
applicationId = com.xfhy.gradledemo
compileSdkVersion = 29
buildToolsVersion = 29.0.2
複製代碼
不錯,已經能搞一個能讀取到閉包信息的插件了.
咱們來實現一個插件,打包的時候將pic/test.png
複製到apk文件中的assets中.其實是在打包以前將test.png複製到相應的文件夾,等待打包合成.首先是新建HookAssetsPlugin.groovy
class HookAssetsPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.afterEvaluate { it ->
//1. 在afterEvaluate閉包中才能獲取當前project中的全部task
project.plugins.withId('com.android.application') {
//2.確保當前project是Android app project,而不是Android library project, 爲給定id的插件執行或註冊操做
project.android.applicationVariants.all { variant ->
//3. 拿到全部變體信息
//[ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=freeDebug, filters=[], versionCode=2, versionName=2.0.0}}]
variant.outputs.each { variantOutput ->
// 4. outputs 字段可知道該字段表明着當前變體的輸出信息(DomainObjectCollection 類型)
// println("${variantOutput.name}") //free-debug free-release
if (variantOutput.name.contains('release')) {
//5. 拿到release
project.tasks.findByName("package${variant.name.capitalize()}").doFirst { task ->
//6. 獲得packageApplication
project.copy {
//7. 複製
from "${project.projectDir.absolutePath}/pic/test.png"
into "${task.assets.provider.value.value.getAbsolutePath()}"
}
}
}
}
}
}
}
}
}
複製代碼
嵌套特別多,寫起來不是很舒服,並且不能智能提示,並且api還很差查....吐血..詳細的註釋在代碼中已給出,這裏就很少作介紹了.使用的時候在app下的build.gradle中添加以下代碼便可:
import com.xfhy.plugin.HookAssetsPlugin
apply plugin: HookAssetsPlugin
複製代碼
而後執行gradlew assembleFreeRelease
,完事兒以後看一下打出來的apk包,能夠看到是apk文件裏面的assets裏面確實多了test.png文件.看起來沒什麼鳥用,可是卻讓咱們感覺到了插件到底能夠幹些什麼事兒.
首先是咱們在執行指令的時候加一個參數gradlew assembleFreeRelease -Dorg.gradle.debug=true --no-daemon
,這樣. 而後在AS->Run->EditConfigurations,而後點擊左上角的+
號,添加一個Remote,而後直接點擊apply便可.
而後點擊debug按鈕便可進入調試.
Gradle插件不少時候能方便咱們進行一些騷操做,用處仍是挺大的.
參考