本文寫的時(shí)候 AndroidStudio版本為3.6.3 Gradle版本為5.6.4 若后續(xù)版本更新可能有版本兼容問題,需要讀者自己適配帜篇,或者參照:
AspectJ的github地址 :https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
本文僅是對(duì)于AspectJ在kotlin中的使用的一個(gè)記錄彻舰,不涉及到切面的概念及其詳細(xì)的說明伐割,
關(guān)于AspectJ的更詳細(xì)的說明:https://blog.csdn.net/zlmrche/article/details/79643801
一、配置
1淹遵、依賴配置
//在項(xiàng)目根目錄下的build.gradle中
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'
--------------------------------------------------------------------------------------------------
//在app或其他module目錄下的build.gradle中
...
apply plugin: 'android-aspectjx'
apply plugin: 'kotlin-kapt'
dependencies {
...
implementation 'org.aspectj:aspectjrt:1.9.5'
}
2口猜、離線配置
先在項(xiàng)目下創(chuàng)建一個(gè)plugins文件负溪,然后下載gradle-android-plugin-aspectjx-2.0.9.jar包透揣,將下載的jar放到plugins文件夾中,在項(xiàng)目的build.glide文件中按照下面的配置進(jìn)行配置川抡,然后讓項(xiàng)目依賴該包(注意是項(xiàng)目依賴)
https://github.com/HujiangTechnology/AspectJX-Demo/tree/master/plugins
dependencies {
...
classpath fileTree(dir:'plugins', include:['*.jar'])
}
注意:上面兩種依賴根據(jù)需要選擇其中一種就行辐真,第一種依賴配置有時(shí)候會(huì)涉及到翻墻(我依賴的時(shí)候在阿里云上是解析不到該庫的需要翻墻)所以更推薦第二種
二、使用
這個(gè)使用的例子是定義一個(gè)打印方法執(zhí)行時(shí)間的例子(在需要打印方法執(zhí)行時(shí)間的方法上用定義的注解修飾崖堤,方法執(zhí)行的時(shí)候會(huì)打印出方法名稱及其執(zhí)行時(shí)間)
/**
* 第一步定義注解(這就是用來修飾需要打印時(shí)間方法的注解)
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PrintFunTime
/**
* 第二步定義切面使用@Aspect修飾一個(gè)類
*/
@Aspect
class Aop {
/**
* 第三步定義切點(diǎn) 使用@Pointcut修飾一個(gè)用@Aspect修飾的類中的方法
* @Pointcut 中execution的參數(shù)表示的是所有帶PrintFunTime注解的方法
此處由于只是一個(gè)簡(jiǎn)單的示例所以只用了這一種方式侍咱,若需要適配更多的方法可以參考
[https://blog.csdn.net/zlmrche/article/details/79643801](https://blog.csdn.net/zlmrche/article/details/79643801)
這里面有更詳細(xì)的說明
*/
@Pointcut("execution(@com.weilai.study.PrintFunTime * *(..))")
fun printFunTime() {}
/**
* 第四步關(guān)聯(lián)切點(diǎn)與處理邏輯方法 使用@Around修飾定義的方法,參數(shù)為第三步的切點(diǎn)方法
*
*/
@Around("printFunTime()")
@Throws(Throwable::class)
fun aroundPrintFunTime(point:ProceedingJoinPoint) {
//獲取調(diào)用方法定義
val method = (point.signature as? MethodSignature)?.method ?: return
//判斷方法上的注解密幔,如果方法上有定義的注解PrintFunTime 打印方法調(diào)用時(shí)間
if (method.isAnnotationPresent(PrintFunTime::class.java)) {
val startTime = System.currentTimeMillis()
point.proceed()
println("printFunTime method ${method.name} time = ${System.currentTimeMillis() - startTime}")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
print()
}
//最后在需要打印時(shí)間的方法上楔脯,用PrintFunTime修飾,當(dāng)print方法被調(diào)用完成的時(shí)候就會(huì)打印其執(zhí)行的時(shí)間
@PrintFunTime
fun print() {
println("小乖乖")
}
以上是一個(gè)簡(jiǎn)單的AspectJ的使用方式胯甩,AspectJ的更多的使用需要根據(jù)業(yè)務(wù)去定義昧廷,比如項(xiàng)目已經(jīng)開發(fā)得差不多了堪嫂,這時(shí)候需要在項(xiàng)目中添加許多的用戶權(quán)限判斷的場(chǎng)景,使用切面的話可以讓開發(fā)過程輕松許多木柬,也好維護(hù)許多皆串。
總的來說,切面的使用就四個(gè)步驟
1眉枕、定義注解
2恶复、定義切面
3、定義切點(diǎn)
4速挑、關(guān)聯(lián)切點(diǎn)及邏輯處理