【Android】AspectJX學習筆記


AspectJX學習筆記

參考文檔:

Introduction to AspectJ
Github: AspectjDemo
Android監測用戶行為之中AOP編程之AspectJ實戰 作者:weixin_33726943
Android中的AOP的實現及AspectJ的使用 作者:岩漿李的游魚
深入理解Android之AOP 作者:阿拉神農

常用概念

Join Points(連接點):簡稱JPoints,是AspectJ的核心思想之一,把程序的整個執行過程划分成幾個關鍵點,包括構造方法調用,調用方法,方法執行,拋出異常等。這些關鍵點可以作為Join Points,將想要執行的內容插入到這些時機中。
Pointcuts(切入點):指定相應Advice需要插入的位置。
Advice(通知):指定代碼將注入到Pointcuts的什么位置。
Aspect(切面):Pointcut和Advice組合到一起,形成了一個明確的位置,也就是切面。

一、Pointcuts切入點

用來描述 JPoint 注入點的一段表達式,比如:調用 Animal 類 fly 方法的地方,call(* Animal.fly(..))。

時機 命令
函數執行(在函數內部) execution(MethodPattern)
函數調用(調用函數的位置) call(MethodPattern)
構造函數執行 execution(ConstructorPattern)
構造函數調用 call(ConstructorPattern)
靜態初始化 staticinitialization(TypePattern)
讀取屬性 get(FieldPattern)
設定屬性 set(FieldPattern)
異常處理(對應catch內的執行) handler(TypePattern)
Advice執行時 adviceexecution()

1、明確指定切入點

方法簽名為void Point.setX(int),Point的setX方法,入參是1個int類型,返回值為void

call(void Point.setX(int))

2、使用條件運算符指定切入點

可以通過&&,||,!進行邏輯運算。

call(void Point.setX(int)) ||
call(void Point.setY(int))

3、使用通配符指定切入點

篩選出Figure類,函數名以make開頭,任意參數,返回值為void的方法。

call(void Figure.make*(..))

4、限定訪問權限的切入點

限定Figure類,任意函數名,任意參數,任意返回值,public方法。

call(public * Figure.* (..))

二、Advice建議

常見的有 Before、After、Around 等,表示代碼執行前、執行后、替換目標代碼,也就是在 Pointcut 何處注入代碼。

注解 用途
Before 在執行JPoint之前
After 在執行JPoint之后
Around 替換原需要執行的代碼,如果需要執行源代碼,可以使用jointPoint.proceed()方法。
AfterReturning 正常return時
AfterThrowing 拋出異常時

三、AspectJX使用

AspectJX是滬江網開源的一個支持Android的AspectJ庫。Github:gradle_plugin_android_aspectjx

1、環境配置

  • 在根目錄的build.gradle增加AspectJX的依賴。
dependencies {
	classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8'
}
  • 修改需要使用AspectJX的模塊的build.gradle。
dependencies {
    // ..
    implementation 'org.aspectj:aspectjrt:1.9.5'
    // ..
}

apply plugin: 'android-aspectjx'

aspectjx {
    //排除部分路徑
    exclude 'android'
    exclude 'com.alibaba'
}

2、創建Aspect類

需要在類上注解@Aspect,函數上注解需要注入的路徑

returning參數可以指明返回值。

package com.irisleon.fridge.util;

import android.util.Log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class TrackHelper {
   private static final String TAG = "TrackHelper";

   @Before("execution(* com.irisleon.fridge.*.*.*(..)) || execution(* com.irisleon.fridge.*.*(..))")
   public void DebugFunctionLog(JoinPoint joinPoint) throws Throwable {
      Log.d(TAG, "----> FuncTrace:" + joinPoint.getSignature());
      Log.d(TAG, "        At:" + joinPoint.getSourceLocation());
      for (Object item : joinPoint.getArgs()) {
         if (item != null) {
            Log.d(TAG, "        Arg:" + item.toString());
         }
      }
   }

   @AfterReturning(pointcut = "execution(* com.irisleon.fridge.*.*.*(..)) || execution(* com.irisleon.fridge.*.*(..))",
         returning = "retVal")
   public void DebugReturnLog(JoinPoint joinPoint, Object retVal) throws Throwable {
      Log.d(TAG, "<---- FuncTrace:" + joinPoint.getSignature());
      if (retVal != null) {
         Log.d(TAG, "        Return:" + retVal);
      }
   }
}

3、效果展示

效果展示

4、使用場景

1)收集用戶點擊事件,入參。不需要侵入式修改每一個點擊事件,只需要統一監聽onClick,onTouch等事件。
2)判斷某個函數是否有調用權限。例如@Around注解。判斷用戶是否已經登錄。如果未登錄,或者沒有權限,則不繼續進行處理。如果可以繼續操作,調用jointPoint.proceed()。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM