1. 程式人生 > >AOP思想在Android專案中的應用

AOP思想在Android專案中的應用

看完本篇文章你將學到什麼?

1.基本瞭解AOP的程式設計思想,以及如何在Android中使用AOP的思想
2.藉助AspectJ用AOP的思想實現埋點邏輯
3.藉助AspectJ用AOP的思想實現遮蔽快速點選事件的處理

什麼是AOP

AOP,字面翻譯為面向切面程式設計。它是一種程式設計思想,不是什麼新技術。可以這麼理解,在Android開發過程中,我們經常會在我們的具體業務程式碼中加入全域性性、系統性的與具體業務無關的程式碼。比如埋點、動態申請許可權等等。AOP的思想就是將這些與業務無關的系統性的功能解耦出來,讓程式碼看起來更清晰一點。使用AOP思想與正常程式流程的對比我們可以通過下面示例圖片有個基礎的認識:

上圖1我們看到是我們正常的程式流程,程式的執行就像水從管道流出一樣從上到下順暢的縱向執行。圖2為我們展示了AOP思想的程式執行流程,從圖中可以看到我們的管道被從某一點橫向的切開(AOP中將這個切點定義為pointCut),然後會在切入點植入一段我們在Aspect(類似於Java的類的理念,AOP中用來管理切點和執行程式碼塊的一個概念)中定義的程式碼。示例僅是一種演示,實際情況是植入執行的程式碼塊可以向被插入方法的前後同時植入程式碼塊。目前實現AOP思想的框架有AspectJ、Spring、JBoss4.0等等。

AspectJ框架

為什麼這裡選擇介紹AspectJ呢?主要是我公司的專案使用的是這個框架。那麼什麼是AspectJ?

它是實現AOP思想的一個框架,擁有自己的編譯器和語法,可以在編譯期間將需要植入的程式碼編譯成Java程式碼插入到你的原始碼檔案當中。更直白點

我們的Android專案引用也非常的簡單,2步就可以搞定:

  • 在專案的根目錄的Build.gradle檔案中加入下面的程式碼:

    1dependencies {
    2    classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
    3}
    
  • 在你的app模組或者其他module中新增依賴:

    1dependencies {
    2   implementation 'org.aspectj:aspectjrt:1.8.9'
    3}
    

應用

我們在專案中經常會遇到一個小問題,就是你對一個View繫結的一個點選事件使用者瘋狂的快速點選導致點選事件的處理程式碼被重複執行,常見的處理方式就是在點選事件中加入時間判斷的邏輯,在短時間內的重複點選不做響應。但是如果有很多點選事件,這樣處理起來顯然讓程式碼不好看。

所以,藉助AspectJ中的AOP思想,可以在解決快速重複點選的問題的同時,可以讓你的程式碼看的更優雅一點。

第一步:自定義一個註解

[email protected](RetentionPolicy.RUNTIME)
[email protected](ElementType.METHOD)
3public @interface IgnoreFastClick {
4    long value() default 2000;
5}

第二步:寫Aspect植入的類

 [email protected]
 2public class IgnoreFastClickAspect {
 3
 4    int lastViewId=-1;
 5    long lastClickTime=0;
 6
 7    @Pointcut("execution(@com.bob.www.testdemo.aop.IgnoreFastClick * *(..))")
 8    public void hhh(){
 9    }
10
11    @Around("hhh()")
12    public void insertCodeBlock(ProceedingJoinPoint joinPoint) throws Throwable {
13        View view;
14        //取click方法中的引數view
15        if (joinPoint.getArgs() != null
16                && joinPoint.getArgs().length > 0
17                && joinPoint.getArgs()[0] instanceof View) {
18            view = ((View) joinPoint.getArgs()[0]);
19            if (view == null)
20                return;
21        } else {
22            return;
23        }
24
25        MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
26        Method method = methodSignature.getMethod();
27        if (method.isAnnotationPresent(IgnoreFastClick.class)) {
28            IgnoreFastClick ignoreFastClick = method.getAnnotation(IgnoreFastClick.class);
29            long nowTime = System.currentTimeMillis();
30            // 如果兩次點選時間差小於或等於value的值,並且兩次點選的是同一個View,就不執行onClick()方法
31            if (nowTime - lastClickTime <= ignoreFastClick.value()
32                    && view.getId() == lastViewId) {
33                Log.d("AOP", "you click is too fast!");
34            } else {
35                // 記住上一次點選的時間戳和View的ID
36                lastViewId = view.getId();
37                lastClickTime = nowTime;
38                執行onCLick()方法
39                joinPoint.proceed();
40            }
41        }
42    }
43}

第三步:給click事件方法加註解

 1    @Override
 2    protected void onCreate(Bundle savedInstanceState) {
 3        super.onCreate(savedInstanceState);
 4        setContentView(R.layout.activity_main);
 5
 6        mTestBtn = findViewById(R.id.btn_test);
 7        mTestBtn.setOnClickListener(new View.OnClickListener() {
 8
 9            @IgnoreFastClick
10            @Override
11            public void onClick(View v) {
12                Log.d("AOP", "----------------"+number++);
13            }
14        });
15    }

以後只要做防重點選的事件,只用加個註解就搞定了。

要想完全掌握AspectJ的語法還是挺多的,這裡只是一個簡單的拋磚引玉的例子哦。讀者可以試試使用AspectJ完成事件統計相關的邏輯哦。講的不好,僅供參考。

如果覺得本文對你有一點點的幫助,關注一下又能有什麼損失呢。
微信搜尋公眾號:南京Android部落

或者微信掃描下方二維碼: