Jet AOP
AOP是OOP的延續(xù)大渤,是軟件開發(fā)中的一個(gè)熱點(diǎn),也是spring框架中的一個(gè)重要內(nèi)容掸绞,是函數(shù)式編程的一種衍生范型泵三。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低衔掸,提高程序的可重用性切黔,同時(shí)提高了開發(fā)的效率。
Jet-AOP框架具篇;雖然xposed纬霞,dexposed非常強(qiáng)大,但由于Android的碎片化比較嚴(yán)重驱显,兼容問題永遠(yuǎn)是一座無法逾越的大山. 因此考慮用AspectJ來實(shí)現(xiàn)诗芜;
參考的主要項(xiàng)目代碼為JakeWharton大神的Hugo。Hugo是一個(gè)非常容易使用埃疫、易擴(kuò)展的Aop例子
更重要的是你可以 實(shí)現(xiàn) 任何AOP(面向切面)的代碼伏恐。具體的實(shí)現(xiàn)參考 AspectJ 功能;
http://www.eclipse.org/aspectj/
- 可以配合Jet 一起使用栓霜,功能更加強(qiáng)大翠桦,開發(fā)速度杠杠的
Jet - :smile: 如果喜歡,請(qǐng)給個(gè)Star:smile:
Fetures
- 重復(fù)的功能胳蛮,可以通過切面的方法來實(shí)現(xiàn)销凑;
部分已實(shí)現(xiàn)的功能 Use
注解名稱 | 作用 | 備注 |
---|---|---|
@JThread | 借助rxjava,異步執(zhí)行app中的方法 | |
@JLogMethod | 將方法的入?yún)⒑统鰠⒍即蛴〕鰜?可以用于調(diào)試 | |
@JTryCatch | 可以安全地執(zhí)行方法,而無需考慮是否會(huì)拋出運(yùn)行時(shí)異常 | |
@JLogTime | 用于追蹤某個(gè)方法花費(fèi)的時(shí)間,可以用于性能調(diào)優(yōu)的評(píng)判 |
@JThread的使用方法:
@JThread
private void useAsync() {
Log.e(TAG, " thread=" + Thread.currentThread().getId());
Log.e(TAG, "ui thread=" + Looper.getMainLooper().getThread().getId());
}
@JLogMethod 等;
@JTryCatch
@JLogTime
@JLogMethod
public int testLog(int k) {
int i = k + 100;
int j = i++;
j=j/0;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return j;
}
LogCat 打咏龃丁:
MainActivity.testLog(..) 方法參數(shù) : [10]
MainActivity.testLog(..) 方法 返回值 : 0
MainActivity.testLog 執(zhí)行時(shí)間: [3ms]
AspectJ 實(shí)現(xiàn) 無侵入方法監(jiān)控例子(View.onClick方法攔截)
Download
在根目錄下的build.gradle中添加
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.8'
}
}
在app 模塊目錄下的build.gradle中添加
apply plugin: 'com.hujiang.android-aspectjx'
...
dependencies {
compile 'com.meiyou.framework:jet-aop:0.0.1'
...
}
基于aspectj的AOP斗幼,無需使用耗費(fèi)性能的反射.不過,需要在build.gradle中配置一下aspectj
待實(shí)現(xiàn) TODO,
待實(shí)現(xiàn)區(qū)域抚垄,列了一些我想到的通用功能蜕窿, 但是項(xiàng)目里面肯定還存在很多通用的功能谋逻;歡迎 各位 提Issue,讓項(xiàng)目更強(qiáng)大桐经;
- @JPermission([int[]])
方法需要的申請(qǐng)的權(quán)限數(shù)組毁兆; 比如:
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
@JAuthorize()
方法是否需要登錄才能調(diào)用,否則跳到登錄頁面阴挣;
更強(qiáng)大的方式可以參考 Apache Shiro使用Kotlin 代碼 重寫气堕;
Problem
- Android Studio的
Instant Run
功能有時(shí)會(huì)對(duì)你的編譯有影響,當(dāng)出現(xiàn)這種情況時(shí)屯吊,關(guān)閉Instant Run功能送巡, - aspectj代碼編譯時(shí)會(huì)報(bào)一些如下的錯(cuò)摹菠,找到對(duì)應(yīng)的庫盒卸,把這個(gè)庫過濾掉就可以了。
aspectjx配置
aspectjx默認(rèn)會(huì)遍歷項(xiàng)目編譯后所有的.class文件和依賴的第三方庫去查找符合織入條件的切點(diǎn)次氨,為了提升編譯效率蔽介,可以加入過濾條件指定遍歷某些庫或者不遍歷某些庫。
includeJarFilter
和excludeJarFilter
可以支持groupId
過濾煮寡,artifactId
過濾虹蓄,或者依賴路徑匹配過濾
aspectjx {
//織入遍歷符合條件的庫
includeJarFilter 'universal-image-loader', 'AspectJX-Demo/library'
//排除包含‘universal-image-loader’的庫
excludeJarFilter 'universal-image-loader'
}
. 忽略groupId為org.apache.httpcomponents
的庫
aspectjx {
excludeJarFilter 'org.apache.httpcomponents'
}
. 忽略artifactId為gson
的庫
aspectjx {
excludeJarFilter 'gson'
}
. 忽略jar alisdk-tlog-1.jar
aspectjx {
excludeJarFilter 'alisdk-tlog-1'
}
- 忽略所有依賴的庫
aspectjx {
excludeJarFilter '.jar'
}