Android AOP 實踐筆記

本文同步自wing的地方酒館

最近博客更新越來越慢了,有兩方面原因:

1.沒啥好寫的。
2.應該沉下心好好沉澱自己,積累一些東西,博客寫的太頻繁有”刷博客“之嫌,還容易浮躁。
浮躁是大忌 ,所以還是沉下心好好學吧。

網上已經有了很多類似的文章,這裏再寫一次是爲了自己當做筆記,主要是對APT,AspectJ、Javassist的簡單實用進行記錄,方便以後翻閱。

AOP是什麼這裏不多作解釋了,個人理解總結下來就是相對於各個垂直深入的業務邏輯,每個業務邏輯深度的某個層面他們有需要共同的特徵,此時對這種特徵進行統一的處理,也就是所謂的AOP(歡迎拍磚哈,技術在討論中提升)

主要應用場景:

  • 權限檢查
  • 日誌記錄
  • 性能監控
  • 埋點操作

Android 下一些可以進行AOP的工具

APT

在編譯時生成 .java 文件。

代表作品 ButterKnife 、 DataBinding、 EventBus3、Dagger2 等。

AspectJ

在.java編譯爲.class的時候,進行代碼注入。

代表作品: Hugo

Javassist

對已經編譯好的class文件進行操作。

代表作品: 各類熱修復框架(爲了解決類校驗問題)。

各個工具操作時機圖

這裏盜一張圖。原圖地址:http://www.jianshu.com/p/dca3e2c8608a

具體用法

APT

APT是編譯時生成代碼的技術, 主要用到了註解 以及處理註解的Process
這裏我寫一個簡單的小例子,來展示如何使用APT,這個例子類似於MVPHelper的功能,但其實是沒有什麼亂用的,只是展示而已。

  • 建立一個module 用於聲明註解。


這裏Contract註解,是爲了標註一個Activity需要使用MVP模式。並且需要自動生成MVP代碼。

  • 再建立另一個module 用於處理這些註解。

注意這裏必須是java庫,也就是說gradle要apply java 插件,否則將引用不到javax包下的內容。

這個時候,我們只需要讓ConrtactProcessor 繼承 AbstractProcess,並且實現process函數去處理這個註解即可。
這裏生成代碼使用了Javapoet, 我們的目標是在Activity上面使用@Contract註解自動生成MVP代碼,並且@Inject自動注入presenter,如下圖:


這些紅掉的代碼,就是我們想要利用APT生成的代碼,@Inject 用於表示注入mPresenter,這樣就不用我們自己new了,當然這裏是最簡單的注入展示。 我們反過來想想,想讓這些代碼可以工作,生成的代碼應該是怎樣的。生成的代碼路徑如下所示:

MVP部分的代碼不多說,來說一說presenter是如何注入的,其實很簡單:


結合上面紅色的代碼看,應該會一目瞭然吧。

關於如何生成代碼,只需要在process方法中使用javapoet即可,代碼比較簡單繁瑣,這裏就不貼了,有需要的可以到文章尾部的鏈接查看代碼。

AspetJ

AspetJ的引入比較簡單,主要是滬江公司對AspetJ進行了一些Android方面的適配。

在gradle添加

classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.10'

以及

apply plugin: 'android-aspectjx'

使用的時候,只需要新建一個類,並且使用@Aspect註解,即可對需要hook的類生效,並且無需直接使用。

因爲在看這個之前有在用Xposed,所以感覺兩個很像,上手很快。

我們將要使用這個工具實現Activity 啓動時間的監控,以及登錄權限管理的注入,以往判斷用戶登錄往往需要每個函數都判斷一下最後執行邏輯,其實這完全可以注入進去,就像”切面“所說,需要登錄的地方,一刀切。

實現Activity啓動時間監控,這裏寫簡單一點,單純的從onCreate開始到onResume結束進行計時操作。

另外一個是登錄檢驗操作,我們理想的事情是給一個函數添加一個註解,並且這個註解來判斷是否登錄執行相應的轉跳提示操作。

示意如下,比如onResume需要判斷是否登錄,只需要一個註解

我們把需要的邏輯判斷寫在@AspetJ 註解的類裏即可。

這樣不管是埋點還是性能監控還是登錄權限檢驗,都可以異常方便的執行。再也不像原先那樣麻煩了。

Javassist

這個需要結合自定義gradle plugin一起操作,大家都知道apk編譯的時候,先把java編譯爲class文件,接下來會變爲dex文件,gradle提供了transform api,可以讓我們class變爲dex之前做任何想做的事情。

首先建立一個buildSrc的module,這裏面創建的類都是groovy的類,所以擴展名要寫groovy。至於內容嘛。。因爲兼容java 隨便你咯-。-

創建一個Plugin,叫做Regsiter, 只需要讓他implement Plugin 插件即可, 此時重寫apply方法,就可以在主工程中apply這個插件。

另外我們需要結合transform, 所以要給android插件註冊一下transform

在transform裏,我們就可以對所有文件進行操作了

ClassInjector 主要是使用Javassist進行對class文件的改變操作。

值得注意的是,如果操作的過程中需要使用android sdk內容,需要手動將 android.jar添加到 ClassPool裏面。否則會提示找不到類的情況。

本文涉及Demo代碼地址
https://github.com/githubwing/AopDemo

歡迎加入Android地方酒館(425983695)一起研究Android技術。

參考文章

1.http://www.jianshu.com/p/dca3e2c8608a
2.http://blog.csdn.net/eclipsexys/article/details/54425414
3.http://blog.csdn.net/u010386612/article/details/51131642

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章