github地址:https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
一. 配置环境
情况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 覆盖拦截方法 为主
定义一个用@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();
}
}