上一篇主要記錄了一些Android的AOP編程的筆記
Android AOP面向切面編程和Gradle插件編寫(一)
這一篇就大概記錄一下我的關(guān)于編寫Gradle插件的筆記吧
如何用Android Studio編寫一個Gradle插件呢
可以參考如何使用Android Studio開發(fā)Gradle插件
首先我們需要先建立一個Android Library的模塊
保留一個build.gradle
文件然后其他的就刪掉吧
建立如下目錄結(jié)構(gòu)
.
├── build.gradle
└── src
└── main
├── groovy
│ └── com
│ └── sundae
│ └── aoplib
│ └── plugin
│ └── AopLibPlugin.groovy
└── resources
└── META-INF
└── gradle-plugins
└── aoplibplugin.properties
像這樣
建立src/main/groovy/包名/文件.groovy 的文件
這個文件使用來編寫插件內(nèi)容的假哎,注意是.groovy
結(jié)尾的文件
在文件中編寫如下內(nèi)容
package com.sundae.aoplib.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
class AopLibPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println("==================")
println(" Gradle插件 ")
println("==================")
}
然后在src/main/resources/META-INF/gradle-plugins(這個路徑不能變撤嫩,這是用來識別插件的路徑)
在目錄下建立 插件名.properties
的文件
文件內(nèi)編寫
implementation-class=com.sundae.aoplib.plugin.AopLibPlugin
(這個路徑對應(yīng)了編寫的插件的路徑)
接著編寫module的build.gradle
文件
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
這樣一個簡單的gradle插件就編寫好了
然而這樣還不好使用這個插件
要使用這個插件我們需要將它編譯發(fā)布到本地的maven中央倉庫里
繼續(xù)在module的build.gradle
文件中寫入
group='com.sundae.aoplib.plugin'
version='0.0.1'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
上面的group和version的定義會被使用,作為maven庫的坐標(biāo)的一部分汗茄,group會被作為坐標(biāo)的groupId,version會被作為坐標(biāo)的version,而坐標(biāo)的artifactId組成即module名,我們讓其取一個別名moduleName踱阿。然后maven本地倉庫的目錄就是當(dāng)前項(xiàng)目目錄下的repo目錄。
這時候钦铁,右側(cè)的gradle Toolbar就會在module下多出一個task
點(diǎn)擊這個Task就會將這個插件模塊發(fā)布到本地maven倉庫里了
這樣就發(fā)布完成了软舌,要使用它我們只需要在app的build.gardle
中加入
buildscript {
repositories {
maven {
url uri('../repo')
}
}
dependencies {
classpath 'com.sundae.aoplib.plugin:aoplib-plugin:0.0.1'
//包名:插件類名:版本號
}
}
apply plugin: 'aoplibplugin' ///插件名
然后build編譯或點(diǎn)sync now一下,就可以看到gradle console中出現(xiàn)了這樣的輸出
這樣一個編寫gradle的插件的流程就結(jié)束了
接下來就是重點(diǎn)了育瓜,接著之前的問題葫隙,如何使用gradle插件自動加入一些編譯器的配置呢
需要在插件類內(nèi)編寫如下內(nèi)容
package com.sundae.aoplib.plugin
import com.android.build.gradle.AppPlugin
import com.android.build.gradle.LibraryPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.compile.JavaCompile
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
class AopLibPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
// println("==================")
// println(" Gradle插件 ")
// println("==================")
if (!project.android) {
throw new IllegalStateException('Must apply \'com.android.application\' or \'com.android.library\' first!')
}
//// 需要分辨是在app的gradle中使用插件還是在module中使用插件
def isApp = false
def isLib = false
isApp = project.plugins.withType(AppPlugin)
isLib = project.plugins.withType(LibraryPlugin)
if (!isApp && !isLib) {
throw new IllegalStateException("'android' or 'android-library' plugin required.")
}
final def log = project.logger
final def variants
if (isApp) {
variants = project.android.applicationVariants
} else {
variants = project.android.libraryVariants
}
//////////////////////////////////////////////////////////////////////////
project.dependencies {
compile 'org.aspectj:aspectjrt:1.8.9'
}
variants.all { variant ->
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.5",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(
File.pathSeparator)]
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler)
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break;
case IMessage.WARNING:
case IMessage.INFO:
log.info message.message, message.thrown
break;
case IMessage.DEBUG:
log.debug message.message, message.thrown
break;
}
}
}
}
}
}
因?yàn)樾枰猘spectj和gradle tool的包的緣故,所以需要將插件的build.gradle內(nèi)容改為
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
compile 'com.android.tools.build:gradle:2.3.0' ///add
compile 'org.aspectj:aspectjtools:1.8.9' ///add
compile 'org.aspectj:aspectjrt:1.8.9' ///add
}
repositories {
mavenCentral()
}
group='com.sundae.aoplib.plugin'
version='0.0.1'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
點(diǎn)擊uploadArchives
重新編譯發(fā)布插件模塊
app項(xiàng)目中重新應(yīng)用這個插件
這樣原本需要配置的二十幾行的編譯器配置代碼就可以直接用幾行代碼調(diào)用插件來完成啦躏仇,是不是不僅方便快捷恋脚,而且代碼一下子清爽了不少呢,哈哈哈哈??
上一波我的源碼(GitHub)一個Android的AOP面向切面編程的小例子
明天十一放假啦焰手,準(zhǔn)備去張家界旅(qiong)游一趟糟描,怕玩結(jié)束回來都忘得差不多了,所以今天熬夜記錄下來书妻。
好了 船响,完事 ,上床睡覺躲履!
ps:菜鳥上路见间,有問題的地方請多指教??