Android aspectJ Aop
阿新 • • 發佈:2018-09-28
ble undle boolean static with 返回 rac gradle 常用 基於aspectJ實現埋點操作
配置環境:
直接使用大神的:https://github.com/JakeWharton/hugo
配置環境:
直接使用大神的:https://github.com/JakeWharton/hugo
先配置
項目 build.gradle
dependencies {
classpath ‘com.jakewharton.hugo:hugo-plugin:1.2.1‘
}
app / build.gradle
apply plugin: ‘com.jakewharton.hugo‘
Advice 切點插入方式。表示在匹配的切點處,用什麽方式去處理,一共有如下幾個類型:
@Around 環繞插入。參數為ProceedingJoinPoint,可以手動包裹代碼後,在需要的條件中調用參數的方法 proceed() 表示執行目標方法
@Before 前置插入。在切點前執行
@After 後置插入。在切點後執行
@After returning。在返回值之後執行
@After throwing。在拋出異常後執行
註意: 只有Around參數是ProceedingJoinPoint,需要調用proceed執行方法,其他的都只是前後插入,不會影響原有代碼的執行
在AspectJ的切入點表達式中最常用的是call和execution
call:調用此方法的地方切點
execution:方法內部切點
表達式說明:
eg:call( com.home.dot..MainActivity.testBefore(..))
第一個表示返回值,
表示返回值為任意類型,後面這個就是典型的包名路徑,其中可以包含 來進行通配,幾個 沒區別。
- 同時,這裏可以通過&&、||、!來進行條件組合。()代表這個方法的參數,你可以指定類型,
- 例如android.os.Bundle,或者(..)這樣來代表任意類型、任意個數的參數
@Aspect public class AspectEntity { public static final String TAG = "AspectEntity"; private boolean isInvokeProceed = true; @Before("execution(* android.app.Activity.on*(..))") public void onStartBefore(JoinPoint joinPoint) { String key = joinPoint.getSignature().toString(); Log.e(TAG, "onStartBefore:" + key); } /** * 第一個*表示返回值,*表示返回值為任意類型,後面這個就是典型的包名路徑,其中可以包含 * 來進行通配,幾個 * 沒區別。 * 同時,這裏可以通過&&、||、!來進行條件組合。()代表這個方法的參數,你可以指定類型, * 例如android.os.Bundle,或者(..)這樣來代表任意類型、任意個數的參數 */ /** * Around呢,從字面含義上來講,也就是在方法前後各插入代碼,是的,他包含了Before和After的全部功能 */ @Around("call(* com.home.dot.androidautodot.MainActivity.testBefore(..))") public void aroundTest(ProceedingJoinPoint joinPoint) throws Throwable { if (isInvokeProceed) {//isInvokeProceed為false則不執行原始方法(也就是不執行testBefore方法的內部代碼) joinPoint.proceed();//代表執行原始的方法 在這之前、之後,都可以進行各種邏輯處理 Log.e(TAG, "aroundTest: test"); } Log.e(TAG, "aroundTest end"); } @Before("execution(* android.view.View.OnClickListener.onClick(..))") public void beforeAction() { Log.e(TAG, "beforeAction: "); } @After("execution(* android.view.View.OnClickListener.onClick(..))") public void afterAction() { Log.e(TAG, "afterAction: "); } /** * withincode的使用 * eg:aspectJ1(),aspectJ2(),aspectJ3()都調用了aspectJTest方法, * 但只想在aspectJ2調用aspectJTest時插入代碼 */ @Pointcut("(call(* *..aspectJTest()))&&withincode(* *..aspectJ2())") public void invokeAspectJTestInAspectJ2() { } @Before("invokeAspectJTestInAspectJ2()") public void beforeInvokeaspectJTestInAspectJ2(JoinPoint joinPoint) throws Throwable { if (joinPoint != null) { Log.e(TAG, "method:" + joinPoint.getSignature()); } } }
Android aspectJ Aop