国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中AOP的應用實踐之過濾重復點擊

2019-10-21 21:38:46
字體:
來源:轉載
供稿:網友

前言

大家對AOP應該都不陌生, 就算沒有用過也肯定聽說過,切面編程一直是一個熱點的話題,AOP即Aspect Oriented Programming的縮寫,習慣稱為切面編程;與OOP(面向對象編程)萬物模塊化的思想不同,AOP則是將涉及到眾多模塊的某一類問題進行統一管理,AOP的優點是將業務邏輯與系統化功能高度解耦,讓我們在開發過程中可以只專注于業務邏輯,其他一些系統化功能(如路由、日志、權限控制、攔截器、埋點、事件防抖等)則由AOP統一處理;

AspectJ簡介

AOP是一種編程思想,或者說方法論,AspectJ則是專為AOP設計的一種語言,它支持原生的JAVA,可用于在java中處理AOP的相關問題;下面非常簡單的描述下AspectJ中幾個要點

Join Points

AspectJ中的切點,是AspectJ作用到具體某個位置的說明,主要包括三類:

  • 函數(函數調用,函數執行,構造函數等)
  • 變量(變量get,變量set等)
  • 代碼塊(靜態代碼塊,for等)

Pointcuts

AspectJ中的切面(這種翻譯不一定正確),由點及面,用于說明你需要hook哪一類問題,比如我需要hook所有的Activity的生命周期方法,則:

@Pointcut("execution(* android.app.Activity.on*(..))") 

advice

Join Points和Pointcuts用來說明需要hook哪些位置或者流程,advice則用于hook之后指定需要做什么,包括:

before() 在切入點之前操作

after() 在切入點之后操作

  • after():returning 函數正常結束
  • after():throwing 函數異常結束

around() 完全替換函數(可以手動再調用原函數)

around()用的會比較多,因為自由度高,其他的用around()都可以實現

AOP處理android中的重復點擊

短時間的重復點擊如果不做處理會帶來不好的體驗且可能引發問題(打開多個頁面,多次提交,數據錯亂),之前我寫過一篇文章使用代理模式+反射來處理重復點擊的問題:Android-如何優雅的處理重復點擊 ,雖然這種方式能達到目的且還算靈活,但還是存在侵入性,對于業務邏輯不是完全透明,所以我們需要使用跟好的方式來處理;

AOP用于處理某一類獨立的問題,非常契合屏蔽重復點擊的需求,我們只需要hook住原先的點擊事件(轉確的說是點擊事件后的處理流程),判斷是不是重復點擊,是則過濾掉不讓它執行,否則就正常執行;

代碼

在Android中進行AspectJ的實現,建議使用Hujiang大神的框架gradle_plugin_android_aspectjx,可以非常方便的集成和配置AspectJ在Android中的環境

集成

//root gradle dependencies { classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.1' }//app或module gradleapply plugin: 'android-aspectjx' //插件compile 'org.aspectj:aspectjrt:1.8.9' //jar

AspectJ代碼

@Aspectpublic class ClickFilterHook { private static Long sLastclick = 0L; private static final Long FILTER_TIMEM = 1000L; @Around("execution(* android.view.View.OnClickListener.onClick(..))") public void clickFilterHook(ProceedingJoinPoint joinPoint) { if (System.currentTimeMillis() - sLastclick >= FILTER_TIMEM) { sLastclick = System.currentTimeMillis(); try { joinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } } else { Log.e("ClickFilterHook", "重復點擊,已過濾"); } }}

測試

 //普通方式 ok mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"有效點擊",Toast.LENGTH_SHORT).show(); } }); //butterknife等IOC框架 ok @OnClick({R.id.btn}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn: Toast.makeText(MainActivity.this,"有效點擊",Toast.LENGTH_SHORT).show(); break; } } //自定義view ok @BindView(R.id.tv_small_up) StrokeTextView mTvSmallUp; ... mTvSmallUp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"有效點擊",Toast.LENGTH_SHORT).show(); } });

可以發現,我們處理重復點擊的代碼,對于原先的代碼是沒有任何耦合的,對于業務邏輯是完全透明,甚至業務邏輯代碼里都沒有體現,這一類問題就已經被處理好了,而且是全局的處理;

說一下上面的代碼中幾個點:

1@Aspect:該注解用于標注使用Aspect的類,即你編寫Aspec代碼的類

2、@Around("...")

3、@Around注解用于標注hook之后的處理代碼,我們這里使用Around是因為原函數(onClick)可能執行,也可能不執行;注解中的參數則對應Pointcuts

  • "execution(* android.view.View.OnClickListener.onClick(..))"對應Pointcuts,即用一個類似正則表達式來告訴控制器你需要hook哪些函數(方法)
  • execution:表示hook的流程是函數執行過程(Join Points有很多種,execution只是其中一種,具體可參見AspectJ官方文檔)
    android.view.View.OnClickListener.onClick(..)) :表示android.view.View.OnClickListener該類(或接口)下的所有名為onClick,參數個數未知,參數類型未知的函數

總結

我們通過面向切面思想來過濾掉了重復點擊的事件,且高度解耦,可以看到代碼非常簡單,AOP重在理解這種思想且找準切入點;AOP在Android中還可以有非常多的應用,如:

  • Android API23+的權限控制
  • 無痕埋點
  • 全局是否登錄流程控制
  • 路由控制
  • 日志系統
  • 事件防抖(重復點擊)
  • ...

后面有機會再聊這些應用;文章如有任何描述不正確或欠妥的地方,還請大家務必提出來我及時改正,免得誤導更多盆友;

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海晏县| 乌鲁木齐县| 东丽区| 榕江县| 麻江县| 台北市| 白山市| 庄河市| 平塘县| 得荣县| 建宁县| 富民县| 兴和县| 会宁县| 金寨县| 绍兴县| 仪征市| 襄樊市| 蓝田县| 开平市| 图们市| 东兴市| 哈密市| 河曲县| 普定县| 康马县| 眉山市| 临颍县| 荔波县| 山阳县| 融水| 绵阳市| 莱芜市| 京山县| 株洲市| 东阳市| 陆河县| 攀枝花市| 墨竹工卡县| 东至县| 南郑县|