Android AOP 實踐筆記

本文同步自wing的地方酒館javascript

最近博客更新愈來愈慢了,有兩方面緣由:php

1.沒啥好寫的。
2.應該沉下心好好沉澱本身,積累一些東西,博客寫的太頻繁有」刷博客「之嫌,還容易浮躁。
浮躁是大忌 ,因此仍是沉下心好好學吧。java

網上已經有了不少相似的文章,這裏再寫一次是爲了本身當作筆記,主要是對APT,AspectJ、Javassist的簡單實用進行記錄,方便之後翻閱。android

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

主要應用場景:github

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

Android 下一些能夠進行AOP的工具

APT

在編譯時生成 .java 文件。api

表明做品 ButterKnife 、 DataBinding、 EventBus三、Dagger2 等。app

AspectJ

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

表明做品: Hugoeclipse

Javassist

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

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

各個工具操做時機圖

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

具體用法

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代碼地址
github.com/githubwing/…

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

參考文章

1.www.jianshu.com/p/dca3e2c86…
2.blog.csdn.net/eclipsexys/…
3.blog.csdn.net/u010386612/…

相關文章
相關標籤/搜索