android 配置aspect_Android AOP之Aspect简单使用

本文介绍了如何在Android项目中配置和使用AspectJ进行AOP编程,包括环境配置、不同模块的配置差异,以及@Around注解的拦截方法。详细讲解了无参数、有参数和回调方法的拦截实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 配置环境

情况1:只在主工程下使用

App下build.gradle

第1步:导包

dependencies{

...

implementation 'org.aspectj:aspectjrt:1.8.1'

}

第2步:配置环境

dependencies{

...

implementation 'org.aspectj:aspectjrt:1.8.1'

}

//>>>>>>>>>>>>>>>>>>>Aspectjrt 在APP主工程下使用的配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

import org.aspectj.bridge.IMessage

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath 'org.aspectj:aspectjtools:1.8.1'

// classpath 'org.aspectj:aspectjweaver:1.8.13'

}

}

repositories {

mavenCentral()

}

final def log = project.logger

final def variants = project.android.applicationVariants

variants.all { variant ->

if (!variant.buildType.isDebuggable()) {

log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")

return;

}

JavaCompile javaCompile = variant.javaCompile

javaCompile.doLast {

String[] args = ["-showWeaveInfo",

"-1.5",

"-inpath", javaCompile.destinationDir.toString(),

"-aspectpath", javaCompile.classpath.asPath,

"-d", javaCompile.destinationDir.toString(),

"-classpath", javaCompile.classpath.asPath,

"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]

log.debug "ajc args: " + Arrays.toString(args)

MessageHandler handler = new MessageHandler(true);

new Main().run(args, handler);

for (IMessage message : handler.getMessages(null, true)) {

switch (message.getKind()) {

case IMessage.ABORT:

case IMessage.ERROR:

case IMessage.FAIL:

log.error message.message, message.thrown

break;

case IMessage.WARNING:

log.warn message.message, message.thrown

break;

case IMessage.INFO:

log.info message.message, message.thrown

break;

case IMessage.DEBUG:

log.debug message.message, message.thrown

break;

}

}

}

}

情况2:有多个module都需要用到

第1步:导包

新建依赖包 aspectjlib, 在依赖库的build.gradle下导包

dependencies {

...

api 'org.aspectj:aspectjrt:1.8.1'

}

注意:这里并没有使用implementation,而是使用了api 导入.

区别:

implementation: 表示导入的包只能在当前module使用。

api: 表示导入的包“大家”都可以使用。

第2步:配置环境

(1). 主工程需要使用的配置: app下 build.gradle 文件

dependencies {

...

api project(':aspectjlib')

}

//>>>>>>>>>>>>>>>>>>>Aspectjrt 在APP主工程下使用的配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

import org.aspectj.bridge.IMessage

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath 'org.aspectj:aspectjtools:1.8.1'

// classpath 'org.aspectj:aspectjweaver:1.8.13'

}

}

repositories {

mavenCentral()

}

final def log = project.logger

final def variants = project.android.applicationVariants

variants.all { variant ->

if (!variant.buildType.isDebuggable()) {

log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")

return;

}

JavaCompile javaCompile = variant.javaCompile

javaCompile.doLast {

String[] args = ["-showWeaveInfo",

"-1.5",

"-inpath", javaCompile.destinationDir.toString(),

"-aspectpath", javaCompile.classpath.asPath,

"-d", javaCompile.destinationDir.toString(),

"-classpath", javaCompile.classpath.asPath,

"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]

log.debug "ajc args: " + Arrays.toString(args)

MessageHandler handler = new MessageHandler(true);

new Main().run(args, handler);

for (IMessage message : handler.getMessages(null, true)) {

switch (message.getKind()) {

case IMessage.ABORT:

case IMessage.ERROR:

case IMessage.FAIL:

log.error message.message, message.thrown

break;

case IMessage.WARNING:

log.warn message.message, message.thrown

break;

case IMessage.INFO:

log.info message.message, message.thrown

break;

case IMessage.DEBUG:

log.debug message.message, message.thrown

break;

}

}

}

}

(2). module使用的配置: module下 build.gradle 文件

注意:每个module使用Aspectj都要这样配置。(暂时没发现更好的解决方法)

dependencies {

...

api project(path: ':aspectjlib')

}

//>>>>>>>>>>>>>>>>>>>Aspectjrt 只在module下使用的配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

import org.aspectj.bridge.IMessage

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath 'org.aspectj:aspectjtools:1.8.1'

// classpath 'org.aspectj:aspectjweaver:1.8.13'

}

}

repositories {

mavenCentral()

}

android.libraryVariants.all { variant ->

JavaCompile javaCompile = variant.javaCompile

javaCompile.doLast {

String[] args = ["-showWeaveInfo",

"-1.5",

"-inpath", javaCompile.destinationDir.toString(),

"-aspectpath", javaCompile.classpath.asPath,

"-d", javaCompile.destinationDir.toString(),

"-classpath", javaCompile.classpath.asPath,

"-bootclasspath", android.bootClasspath.join(

File.pathSeparator)]

MessageHandler handler = new MessageHandler(true)

new Main().run(args, handler)

def log = project.logger

for (IMessage message : handler.getMessages(null, true)) {

switch (message.getKind()) {

case IMessage.ABORT:

case IMessage.ERROR:

case IMessage.FAIL:

log.error message.message, message.thrown

break

case IMessage.WARNING:

case IMessage.INFO:

log.info message.message, message.thrown

break

case IMessage.DEBUG:

log.debug message.message, message.thrown

break

}

}

}

}

总结规则

1.module使用时,implementation 导入换成api

每个module都要配置环境,包括主工程

使用的时候,主工程和每个module之间的Aspectjrt类互相独立

二. 使用方法

这里主要以@Around 覆盖拦截方法 为主

8cb0a1450cbb

Aspectjrt 使用.png

定义一个用@Aspect 修饰的类,然后在里面写拦截方法

@Aspect

public class TestAspect {

}

1. 无参数

(1) 普通方法

以下方法会拦截 MainActivity.test() 方法的执行, 如果MainActivity.test() 想继续执行,则加多一句 joinPoint.proceed(); 。

@Around("execution(* com.liys.aop.MainActivity.test())")

public void noParam(ProceedingJoinPoint joinPoint) throws Throwable{

//joinPoint.proceed(); //方法继续执行

}

(2) 注解

//SingleClick.java

@Retention(RetentionPolicy.RUNTIME)

public @interface SingleClick {}

//TestAspect.java

@Around("execution(@com.liys.aop.SingleClick * *(..))")

public void noParams(ProceedingJoinPoint joinPoint) throws Throwable {

joinPoint.proceed();

}

//MainActivity.java

@SingleClick

public void test(){}

2. 有参数

(1) 普通方法

//@Around("execution(* com.liys.aop.MainActivity.test(String,..))")

@Around("execution(* com.liys.aop.MainActivity.test(..))")

public void param(ProceedingJoinPoint joinPoint) throws Throwable {

//获取方法上的参数

Object[] args = joinPoint.getArgs();

//情况1: 返回原来的参数

joinPoint.proceed();

//情况2: 参数经过处理后返回

joinPoint.proceed(new Object[]{" "});

}

(2) 注解

//SingleClick.java

@Retention(RetentionPolicy.RUNTIME)

public @interface SingleClick {

int value();

}

//TestAspect.java

@Around("execution(@com.liys.aop.SingleClick * *(..)) && @annotation(singleClick)")

public void params(ProceedingJoinPoint joinPoint, SingleClick singleClick) throws Throwable {

//获取参数

int value = singleClick.value();

}

//MainActivity.java

@SingleClick(123)

public void test(String num, String pw){}

3. 回调

//MainActivity.java

public class MainActivity extends AppCompatActivity implements ITest{

@Override

public void add() {} //回调

}

// ITest.java

public interface ITest {

void add();

}

@Around("execution(* com.liys.aop.MainActivity.test(..))")

public void callback(ProceedingJoinPoint joinPoint) {

Object obj = joinPoint.getThis();

if (obj instanceof ITest) {

((Test) activity).add();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值