本文寫的時候 AndroidStudio版本為3.6.3 Gradle版本為5.6.4 若后續版本更新可能有版本兼容問題,需要讀者自己適配,或者參照:
AspectJ的github地址 :https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
本文僅是對于AspectJ在kotlin中的使用的一個記錄,不涉及到切面的概念及其詳細的說明,
關于AspectJ的更詳細的說明:https://blog.csdn.net/zlmrche/article/details/79643801
一、配置
1、依賴配置
//在項目根目錄下的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、離線配置
先在項目下創建一個plugins文件,然后下載gradle-android-plugin-aspectjx-2.0.9.jar包,將下載的jar放到plugins文件夾中,在項目的build.glide文件中按照下面的配置進行配置,然后讓項目依賴該包(注意是項目依賴)
https://github.com/HujiangTechnology/AspectJX-Demo/tree/master/plugins
dependencies {
...
classpath fileTree(dir:'plugins', include:['*.jar'])
}
注意:上面兩種依賴根據需要選擇其中一種就行,第一種依賴配置有時候會涉及到翻墻(我依賴的時候在阿里云上是解析不到該庫的需要翻墻)所以更推薦第二種
二、使用
這個使用的例子是定義一個打印方法執行時間的例子(在需要打印方法執行時間的方法上用定義的注解修飾,方法執行的時候會打印出方法名稱及其執行時間)
/**
* 第一步定義注解(這就是用來修飾需要打印時間方法的注解)
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PrintFunTime
/**
* 第二步定義切面使用@Aspect修飾一個類
*/
@Aspect
class Aop {
/**
* 第三步定義切點 使用@Pointcut修飾一個用@Aspect修飾的類中的方法
* @Pointcut 中execution的參數表示的是所有帶PrintFunTime注解的方法
此處由于只是一個簡單的示例所以只用了這一種方式,若需要適配更多的方法可以參考
[https://blog.csdn.net/zlmrche/article/details/79643801](https://blog.csdn.net/zlmrche/article/details/79643801)
這里面有更詳細的說明
*/
@Pointcut("execution(@com.weilai.study.PrintFunTime * *(..))")
fun printFunTime() {}
/**
* 第四步關聯切點與處理邏輯方法 使用@Around修飾定義的方法,參數為第三步的切點方法
*
*/
@Around("printFunTime()")
@Throws(Throwable::class)
fun aroundPrintFunTime(point:ProceedingJoinPoint) {
//獲取調用方法定義
val method = (point.signature as? MethodSignature)?.method ?: return
//判斷方法上的注解,如果方法上有定義的注解PrintFunTime 打印方法調用時間
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()
}
//最后在需要打印時間的方法上,用PrintFunTime修飾,當print方法被調用完成的時候就會打印其執行的時間
@PrintFunTime
fun print() {
println("小乖乖")
}
以上是一個簡單的AspectJ的使用方式,AspectJ的更多的使用需要根據業務去定義,比如項目已經開發得差不多了,這時候需要在項目中添加許多的用戶權限判斷的場景,使用切面的話可以讓開發過程輕松許多,也好維護許多。
總的來說,切面的使用就四個步驟
1、定義注解
2、定義切面
3、定義切點
4、關聯切點及邏輯處理