欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

如何在Android項目中使用AspectJ方法

如何在Android項目中使用AspectJ方法?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)建站服務項目包括贛州網(wǎng)站建設、贛州網(wǎng)站制作、贛州網(wǎng)頁制作以及贛州網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯(lián)網(wǎng)行業(yè)的解決方案,贛州網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到贛州省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!

Android是什么

Android是一種基于Linux內(nèi)核的自由及開放源代碼的操作系統(tǒng),主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯(lián)盟領導及開發(fā)。

什么是AOP

AOP是 Aspect Oriented Programming 的縮寫,即面向切面編程,和平常遇到的面向對象OOP編程不一樣的是,OOP是將功能模塊化對象化,AOP是針對同一類的問題統(tǒng)一化處理。例如做日志埋點,性能監(jiān)控,動態(tài)權限控制等。

AspectJ

AspectJ實際上是對AOP編程的實踐,目前還有很多的AOP實現(xiàn),如ASMDex,但筆者選用的是AspectJ。

在Android項目中使用AspectJ

如果使用原生AspectJ在項目中配置會非常麻煩,在GitHub上有個開源的SDK gradle_plugin_android_aspectjx基于gradle配置即可。

接入說明

請自行查看開源項目中的接入配置過程

AspectJ 之 Join Points介紹

Join Points在AspectJ中是關鍵的概念。Join Points可以看做是程序運行時的一個執(zhí)行點,比如:一個函數(shù)的調(diào)用可以看做是個Join Points,相當于代碼切入點。但在AspectJ中,只有下面幾種執(zhí)行點是認為是Join Points:

Join Points說明實例
method call函數(shù)調(diào)用比如調(diào)用Log.e(),這是一個個Join Point
method execution函數(shù)執(zhí)行比如Log.e()的執(zhí)行內(nèi)部,是一處Join Points。注意這里是函數(shù)內(nèi)部
constructor call構造函數(shù)調(diào)用和method call 類似
constructor execution構造函數(shù)執(zhí)行和method execution 類似
field get獲取某個變量比如讀取DemoActivity.debug成員
field set設置某個變量比如設置DemoActivity.debug成員
pre-initializationObject在構造函數(shù)中做的一些工作。-
initializationObject在構造函數(shù)中做的工作。-
static initialization類初始化比如類的static{}
handler異常處理比如try catch 中,對應catch內(nèi)的執(zhí)行
advice execution這個是AspectJ 的內(nèi)容-

Pointcuts 介紹

一個程序會有多個Join Points,即使同一個函數(shù),也還分為call 和 execution 類型的Join Points,但并不是所有的Join Points 都是我們關心的,Pointcuts 就是提供一種使得開發(fā)者能夠值選擇所需的JoinPoints的方法。

Advice

Advice就是我們插入的代碼可以以何種方式插入,有Before 還有 After、Around。
下面看個例子:

@Before(“execution(* android.app.Activity.on**(..)))”)
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable{
}

這里會分成好幾個部分,我們依次來看:

  1. @Before: Advice, 也就是具體的插入點

  2. execution:處理Join Point的類型,例如call、execution

  3. (* android.app.Activity.on**(..)): 這個是最重要的表達式,第一個*表示返回值,*表示返回值為任意類型,后面這個就是典型的包名路徑,其中可以包含 *來進行通配,幾個 *沒有區(qū)別。同時這里可以通過&&、||、!來進行條件組合。()代表這個方法的參數(shù),你可以指定類型,例如android.os.Bundle,或者 (..) 這樣來代表任意類型、任意個數(shù)的參數(shù)。

  4. public void onActivityMehodBefore: 實際切入的代碼。

Before 和 After 其實還是很好理解的,也就是在Pointcuts之前和之后,插入代碼,那么Android呢,從字面含義上來講,也就是在方法前后各插入代碼,他包含了 Before和 After 的全部功能,代碼如下:

@(“execution(* com.xys.aspectjxdemo.MainActivity.testAOP()))”)
public void onActivityMethodAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
String key = proceedingJoinPoint.getSignature().toString();
Log.d(TAG,”onActivityMethodAroundFirst:”+key);
proceedingJoinPoint.proceed();
Log.d(TAG,”onActivityMethodAroundSecond:”+key);
}

以上代碼中,proceedingJoinPoint.proceed()代表執(zhí)行原始的方法,在這之前、之后,都可以進行各種邏輯處理。

自定義Pointcuts

自定義Pointcuts可以讓我們更加精準的切入一個或多個指定的切入點。

首先我們要定義一個注解類

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface DebugTrace {
}

在需要插入代碼的地方加入這個注解,例如在MainActivity中加入:

public class MainActivity extends AppCompatActivity{
final String TAG = MainActivity.class.getSimpleName();

@Override
protedcted void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
logTest();
}

@DebugTrace
public void logTest(){
Log.e(TAG,”log test");
}
}

最后創(chuàng)建切入代碼

@Pointcut(“execution(@com.kun.aspectjtest.aspect.DebugTrace * *..*.*(..))”)
public void DebugTraceMethod(){}

@Before(“DebugTraceMethod()”)
public void beforeDebugTraceMethod(JoinPoint joinPoint) throws Throwable{
String key = joinPoint.getSignature().toString();
Log.e(TAG, “beforeDebugTraceMethod:”+key);
}

Call

在AspectJ的切入點表達式中,我們前面都是使用的execution,實際上還有一種類型—call,那么這兩種語法有什么區(qū)別呢?對call來說:

Call (Before)
Pointcut{
Pointcut Method
}
Call (After)

對Execution來說:

Pointcut{
execution (Before)
Pointcut Method
execution (After)
}

Withincode

這個語法通常來進行一些切入點條件的過濾,作更加精確的切入控制,如下:

public class MainActivity extends AppCompatActivity{
final String TAG = MainActivity.class.getSimpleName();

@Orveride
protected void onCreate(Bundle savedInstanceState){
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_main);
aspectJ1();
aspectJ2();
aspectJ3();
}
public void aspectJTest(){
Log.e(TAG,”execute aspectJTest");
}

public void aspectJ1(){
aspectJTest();
}
public void aspectJ2(){
aspectJTest();

}
public void aspectJ3(){
aspectJTest();
}
}

aspectJ1(),aspectJ2(),aspectJ3()都調(diào)用了aspectJTest方法,但只想在aspectJ2調(diào)用aspectJTest時插入代碼,這個時候就需要使用到Pointcut和withcode組合的方式,來精確定位切入點。

@Pointcut(“(call(* *..aspectJTest()))&&withincode(* *..aspectJ2())”)
public void invokeAspectJTestInAspectJ2(){
}

@Before(“invokeAspectJTestInAspectJ2()”)
public void beforeInvokeaspectJTestInAspectJ2(JoinPoint joinPoint) throws Throwable{
Log.e(TAG,”method:”+getMethodName(joinPoint).getName());
}

private MethodSignature getMethodName(JoinPoint joinPoint){
if(joinPoint == null) return null;
return (MethodSignature) joinPoint.getSignature();
}

execution 語法

execution()是最常用的切點函數(shù),其語法如下所示:

例如下面這段語法:@Around(“execution(* *..MainActivity+.on*(..))")

整個表達式可以分為五個部分:
1.execution()是表達式主體
2.第一個*號代表返回類型,*號代表所有的類型。
3.包名 表示需要攔截的包名,這里使用*.代表匹配所有的包名。
4.第二個*號表示類名,后面跟.MainActivity是指具體的類名叫MainActivity。
5.*(..) 最后這個星號表示方法名,+.代表具體的函數(shù)名,*號通配符,包括括弧號里面表示方法的參數(shù),兩個dot代表任意參數(shù)。

遇到的錯誤

1.以下錯誤可以使用gradle2.2.3解決,由于目前還不適配gradle3.0導致的

Error:Execution failed for task ':app:transformClassesWithDexBuilderForDebug'.
> Unexpected scopes found in folder '/Users/ram/WorkSpace/AndroidWorkSpace/MyDemo/app/build/intermediates/transforms/AspectTransform/debug'. Required: PROJECT, SUB_PROJECTS, EXTERNAL_LIBRARIES. Found: EXTERNAL_LIBRARIES, PROJECT, PROJECT_LOCAL_DEPS, SUB_PROJECTS, SUB_PROJECTS_LOCAL_DEPS

關于如何在Android項目中使用AspectJ方法問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關知識。

當前文章:如何在Android項目中使用AspectJ方法
URL地址:http://chinadenli.net/article14/gepede.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護用戶體驗網(wǎng)站制作網(wǎng)頁設計公司App設計動態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司