一、前言
通常android系統需要做一些統一的處理,最簡單的選擇是在BaseActivity中,但是由於BaseActivity的
1,強侵入性(改變原有代碼結構)
2,java的硬編碼特性(在預編譯階段需要存在才能處理,但大部分源碼sdk已經寫死了不可能單獨生成自己的一個sdk)
這樣就使得AOP特別的火爆,這裏以入門基礎hook爲知識點,以最簡單的防抖處理爲例實戰一下。
java常用編程思想面向過程(POP)、面向對象(OOP)、面向接口(IOP)、面向切面(AOP)區別:
- 面向過程:典型的是C/C++的結構體,結構體裏只有變量,沒有處理變量的方法,需要專門編寫處理變量的方法。
- 面向對象:ArrayList list=new ArrayList();壞處是如果改爲LinkedList,所有代碼可能需要重寫,同時擴展一個新的List的話,需要重新調用。
- 面向接口:List=new Arraylist();是面向對象的一種形式,廣義上講,抽象類也是接口的一種形式,使用該類的某種屬性(接口)來表示,降低耦合性,增加代碼複用性。
- 面向切面:這種在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。
二、環境配置
首先我們需要配置SpringAOP的插件依賴,在項目根目錄下配置插件版本,並且在需要依賴的module中依賴該插件,同時也要引入該jar包。
三、AOP代碼實現
這裏我們新建一個帶插件註解的類作爲aop的入口,然後在該類中聲明具體的攔截器。從攔截器返回的連接點中取出我們的實例對象view,從而實現務無侵入式點擊事件的攔截。
@Aspect
public class AspectDoubleClick {
private long delayTime = 2000;
private long lastTime; //上次間隔時間
private View lastView; //點擊的view
@Around("execution(* android.view.View.OnClickListener.onClick(..))")
public void onClickListener(ProceedingJoinPoint joinPoint) throws Throwable {
//獲取連接點方法運行時的入參列表(這裏攔截的是觸發增強動作的控件)
Object[] args = joinPoint.getArgs();
View view = (View) args[0];//這裏取第一個即可
if (view != lastView) { //不是同一個View直接過
joinPoint.proceed();
lastView = view;
lastTime = System.currentTimeMillis();
return;
}
if (System.currentTimeMillis() - lastTime >= delayTime) {
joinPoint.proceed();
lastTime = System.currentTimeMillis();
lastView = view;
}
}
}
到此一個簡單的防重複點擊已經實現,可以算結束了,編譯的時候會注意clean project。我們運行項目效果圖如下
三、完美實現
但是這裏統一攔截仍存在以下弊端
1,部分點擊事件不需要攔截如何處理 2,部分點擊事件需要延遲的與全局的2000ms不一樣如何簡單處理
3,部分activity中的頁面都不需要攔截如何統一處理 4,絕大部分事件是帶有狀態的如何簡單處理(比如登錄了才能點擊)
5,在統一攔截下,只有極少個點擊事件需要特殊自定義的如何處理 那麼後面可以參看這個詳細版的,源代碼註釋明確
https://download.csdn.net/download/liuxingyuzaixian/12207685
6,另外推薦基礎學習安卓AOP三劍客:APT,AspectJ,Javassist