AOP埋點從入門到放棄(三)

筆墨Android發表於2018-08-21

前兩篇文章已經很好的說明了AOP的使用方式,但是話說回來了,在專案中有什麼卵用?能幫到我平時開發嗎?

其實我就喜歡這麼直接的朋友,其實一開始的時候我也是這麼覺得的!我花了這麼長時間學習這個東西到底有什麼卵用?但是後來我漸漸的發現這個東西還是挺有用的,平時能幫助到我們節省很多程式碼的!好了,廢話不多說直接說說這個東西在專案中到底有什麼卵用!!!

一張復仇者聯盟鎮樓(感興趣的我可以發你)!皮一下就是這麼開森。。。

AOP埋點從入門到放棄(三)

AspectJ在專案中的卵用

  • 解決一些判斷條件登入的問題;
  • 解決一些埋點的問題;
  • 還有些就有待於發現了...

1. 解決一些判斷條件登入的問題

不知道大家在專案中有沒有這樣的需求?APP有些內容是需要登入才能繼續向下走的,這個時候你需要先判斷使用者是否登入,然後再能往下走,這個需求很常見。但是如果有了AOP這個框架的話,再也不用if/else了,也不用在每一地方都if/else了。

AOP埋點從入門到放棄(三)

好了,實現的效果說完了,那麼我們開始裝逼吧!!!

對於這個需求,如果之前你看了上兩篇文章的話,那麼這個需求就可以說是so easy了,我們看看怎麼實現的吧!

1.1 首先你需要一個註解,是長這樣的!

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CheckLogin {
}
複製程式碼

這就是一個註釋在方法上的註解!!!僅此而已。。。

1.2 寫相應的切面方法。

先來看下程式碼,然後我們在講解

@Aspect
public class LoginAspect {
    private static final String TAG = LoginAspect.class.getSimpleName();

    @Around("execution(@com.jinlong.aspectjdemo.CheckLogin * *(..))")
    public Object beforeDebugTraceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        Method method = signature.getMethod();
        Log.e(TAG, "beforeDebugTraceMethod: " + method.toString());

        //獲取上下文的方法
        Context context = (Context) joinPoint.getThis();

        if (APP.isIsLogin()) {
            return joinPoint.proceed();
        } else {
            Intent intent = new Intent(context, MainActivity.class);
            context.startActivity(intent);
            return null;
        }
    }
}
複製程式碼

說明幾點問題:

  • 萬用字元:這個我不講了,上一篇部落格已經講解了,如果有什麼不理解的,可以看看AOP埋點從入門到放棄(二) 這篇文章!
  • 其實我主要想說的就是裡面的這些判斷的程式碼**Context context = (Context) joinPoint.getThis();**其實這裡返回的是當前執行的物件,有可能是空的,因為我是在Activity中執行的點選時間,所以這裡強轉成上下文是沒問題的,但是如果你要是寫在Fragment的話,就要在獲取一下了!
  • 這裡其實是可以傳遞相應的資料的,但是隻能是相應的基本的資料方式String、int 等;怎麼傳遞呢?這個就涉及到註解的問題了,所以這裡只貼出相應的程式碼了,不再本文的講解中!!!

首先註解程式設計這個樣子了:就是新增了一個相應傳遞的值。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CheckLoginDefault {
    String param1() default "";
}
複製程式碼

然後看怎麼獲取?

    @Around("execution(@com.jinlong.aspectjdemo.CheckLoginDefault * *(..))")
    public void beforeDebugCheckLogin(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        Method method = signature.getMethod();
        CheckLoginDefault annotation = method.getAnnotation(CheckLoginDefault.class);

        Log.e(TAG, "註解傳遞的值為:" + annotation.param1());

        Context context = (Context) joinPoint.getThis();

        Toast.makeText(context, "註解傳遞的值為\n" + annotation.param1(), Toast.LENGTH_SHORT).show();
    }
複製程式碼

裡面註解傳遞的值為:Log列印出來的值。這裡由於沒有執行之前方法的內容,所以不會列印前面方法的Toast了!

最後看看怎麼用?

    @CheckLoginDefault(param1 = "token")
    public void checkLoginDefault(View view) {
        Toast.makeText(this, "執行下一步操作", Toast.LENGTH_SHORT).show();
    }
複製程式碼

通過param1新增相應的引數就可以了,這樣你就可以在點選的時候進行相應的處理了!!!

2. 解決專案中的埋點問題

首先確定好一個問題,你們專案埋點要埋些什麼東西?比如點選事件,或者方法的執行時間?這些都是比較簡單的內容,但是如果你要在某個點選事件的時候,還想獲取相應的內容,這個時候就比較複雜了,怎麼說呢?因為註解只能傳遞相應的基本型別引數(也可能是我自己的只是層面有限),所以這裡存在一定的問題?什麼樣的問題呢?埋點的時候,怎麼區分這些型別,只有在你傳的時候區分了,新增註解的時候去區分,就沒有然後了。至於其他的一些內容,看你們產品需要什麼,需要什麼埋什麼! 這裡就直接上兩個簡單的例子吧!

2.1 相應方法的埋點

    @Before("execution(* android.app.Activity.on*(..))")
    public void onActivityMethodBefore(JoinPoint joinPoint) {
        String key = joinPoint.getSignature().toString();
        Log.e(TAG, "onActivityMethodBefore: 切面的點執行了!" + key);
    }
複製程式碼

2.2 相應方法的執行時間

    @Around("call(* com.jinlong.aspectjdemo.MainActivity.callMethod(..))")
    public void aroundCallMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        joinPoint.proceed();
        long endTime = System.currentTimeMillis();
        Log.e(TAG, "方法執行的時間為" + (endTime - startTime));
    }
複製程式碼

這裡就不詳細講解了!細節前面都講了。至於埋點東西多的話,可以參照上面那個傳遞引數的,總之怎麼簡單怎麼來!!!


除了AOP實現6.0以上許可權的內容,基本上專案中就這些使用的地方,因為最近公司開了一個新專案,所以比較忙,沒有時間去看關於許可權的問題!其實關於AOP實現6.0以上許可權的內容,很多的內容都要講,估計沒有時間細看,所以等忙完這個專案後,我會仔細看一下給夥伴們講,如果現在講的話,怕有些地方講錯了,對不起廣大小夥伴!!!

相關文章