aop學習 深入理解Android之AOP
什么是AOP
AOP是Aspect Oriented Programming的縮寫,即『面向切面編程』。它和我們平時接觸到的OOP都是編程的不同思想,OOP,即『面向對象編程』,它提倡的是將功能模塊化,對象化,而AOP的思想,則不太一樣,它提倡的是針對同一類問題的統一處理,當然,我們在實際編程過程中,不可能單純的安裝AOP或者OOP的思想來編程,很多時候,可能會混合多種編程思想,大家也不必要糾結該使用哪種思想,取百家之長,才是正道。
那么AOP這種編程思想有什么用呢,一般來說,主要用于不想侵入原有代碼的場景中,例如SDK需要無侵入的在宿主中插入一些代碼,做日志埋點、性能監控、動態權限控制、甚至是代碼調試等等。
AspectJ
AspectJ實際上是對AOP編程思想的一個實踐,當然,除了AspectJ以外,還有很多其它的AOP實現,例如ASMDex,但目前最好、最方便的,依然是AspectJ。
在Android項目中使用AspectJ
在android中配置aspectj是特別麻煩的,嘗試在android studio中直接配置aspectj,折騰了半天沒有成功,就放棄了,還好github上有個開源的sdkhttps://github.com/HujiangTechnology/gradle_plugin_android_aspectjx,可以直接拿來用,很方便。
接入說明
在項目的根目錄的build.gradle文件中添加依賴,修改后文件如下
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
然后在項目或者庫的build.gradle文件中添加AspectJ的依賴
compile 'org.aspectj:aspectjrt:1.8.9'
同時在該文件中加入AspectJX模塊
apply plugin: 'android-aspectjx'
aspectjx默認會遍歷項目編譯后所有的.class文件和依賴的第三方庫去查找符合織入條件的切點,為了提升編譯效率,可以加入過濾條件指定遍歷某些庫或者不遍歷某些庫。
includeJarFilter和excludeJarFilter可以支持groupId過濾,artifactId過濾,或者依賴路徑匹配過濾
aspectjx {
//織入遍歷符合條件的庫
includeJarFilter 'universal-image-loader', 'AspectJX-Demo/library'
//排除包含‘universal-image-loader’的庫
excludeJarFilter 'universal-image-loader'
}
使用
創建一個AspectTest的類,
@Aspect
public class AspectTest {
final String TAG = AspectTest.class.getSimpleName();
@Before("execution(* *..MainActivity+.on**(..))")
public void method(JoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String className = joinPoint.getThis().getClass().getSimpleName();
Log.e(TAG, "class:" + className);
Log.e(TAG, "method:" + methodSignature.getName());
}
}
MainActivty的代碼如下
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
log如下
通過build之后會生成一個aspected.jar的文件
反編譯這個jar,會發現它在MainActivity的onCreate中插入了幾行代碼。