android面向切面编程,GitHub - iceCola7/AspectSample: 一个基于 AspectJ 实现 android 面向切面编程的案例。...

本文介绍基于AspectJ实现Android面向切面编程的案例。阐述了AspectJ的原理、优点,如非侵入式监控、学习成本低等。指出其已知问题,如不支持Kotlin等。还给出官方库集成配置步骤,并列举了拦截Activity生命周期方法、自定义注解、点击事件等使用案例。

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

AspectSample

一个基于 AspectJ 实现 android 面向切面编程的案例。

AspectJ 简介

AspectJ 意思就是 Java 的 Aspect。它就是一个代码编译器,在Java编译器的基础上增加了一些它自己的关键字识别和编译方法。

AspectJ编译器在编译期对所切点所在的目标类进行了重构,在编译层将AspectJ程序与目标程序进行双向关联,生成新的目标字节码,即将AspectJ的切点和其余辅助的信息类段插入目标方法和目标类中,同时也传回了目标类以及其实例引用,这样便能够在AspectJ程序里对目标程序进行监听甚至操控。

AspectJ 的优点

非侵入式监控: 可以在不修监控目标的情况下监控其运行,截获某类方法,甚至可以修改其参数和运行轨迹!

学习成本低: 它就是Java,只要会Java就可以用它。

功能强大,可拓展性高: 它就是一个编译器+一个库,可以让开发者最大限度的发挥,实现形形色色的AOP程序!

官方库集成配置

已知问题

不支持kotlin

不能拦截jar包中的类

拦截规则不能写在jar包中

需要在每一个module都配置脚本

配置

1、在 【project】 的 build.gradle 中配置:

buildscript {

repositories {

google()

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:3.3.1'

// aspectj

classpath 'org.aspectj:aspectjtools:1.8.13'

classpath 'org.aspectj:aspectjweaver:1.8.13'

}

}

2、在 【project】 的 build.gradle 最后面添加脚本:

注意,直接粘贴到 build.gradle 文件的末尾即可,不要嵌套在别的指令中

// AOP需要执行的脚本,每一个application和library都需要

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

def aop(variants) {

variants.all { variant ->

JavaCompile javaCompile = variant.javaCompile

String[] args;

javaCompile.doFirst {

args = ["-showWeaveInfo",

"-1.8",

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

"-aspectpath", javaCompile.classpath.asPath,

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

"-classpath", path,

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

}

javaCompile.doLast {

new Main().run(args, new MessageHandler(false));

}

}

}

3、在 【module】 的 build.gradle 中添加依赖:

注意,只在基础module中使用api方式依赖即可

api 'org.aspectj:aspectjrt:1.8.13'//只在基础module中使用api方式依赖

4、在 【module】 的 build.gradle 中添加编译脚本:

注意,直接粘贴到build.gradle文件的开始位置或末尾即可,不要嵌套在别的指令中

如果是 【application】

rootProject.aop(project.android.applicationVariants)

如果是【library】

rootProject.aop(project.android.libraryVariants)

AspectJ 使用案例

定义拦截 Activity 生命周期方法的逻辑

@Aspect

public class TreeAspect {

private static final String TAG = "cxz----->>";

/**

* 切入点:Activity 中以 on 开头的所有方法执行之前

*/

@Before("execution(* android.app.Activity.on*(..))")

public void onActivityMethodBefore(JoinPoint joinPoint) {

String key = joinPoint.getSignature().toString();

Log.e(TAG, "onActivityMethodBefore: 切面的方法执行了--" + key);

}

}

定义拦截自定义注解的逻辑

定义自定义注解

@Retention(RetentionPolicy.CLASS)

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})

public @interface DebugTree {

}

定义拦截规则(注意要更改为正确的包名)

@Aspect

public class AnnotationAspect {

private static final String TAG = "cxz----->>";

// 切入点: DebugTree 注解

@Pointcut("execution(@com.cxz.aspect.sample.DebugTree * * (..))")

public void DebugTraceMethod() {

}

@Before("DebugTraceMethod()")

public void beforeDebugTraceMethod(JoinPoint joinPoint) {

String key = joinPoint.getSignature().toString();

Log.e(TAG, "注解方法之前执行: " + key);

}

@After("DebugTraceMethod()")

public void afterDebugTraceMethod(JoinPoint joinPoint) {

String key = joinPoint.getSignature().toString();

Log.e(TAG, "注解方法之后执行: " + key);

}

}

定义拦截点击事件的逻辑(案例:处理防止连续点击的逻辑)

拦截所有 Vie w或其子类的 【onClick方法】 ,添加防止连续点击的逻辑

@Aspect

public class ClickListenerAspect {

private static final String TAG = "cxz----->>";

private static Long lastClick = 0L;

private static final Long FILTER_TIME = 1000L;

/**

* 切入点:View 中 OnClickListener 接口的 onClick 方法

*/

@Around("execution(* android.view.View.OnClickListener.onClick(..))")

public void clickFilter(ProceedingJoinPoint proceedingJoinPoint) {

if (System.currentTimeMillis() - lastClick >= FILTER_TIME) {

lastClick = System.currentTimeMillis();

try {

proceedingJoinPoint.proceed();

} catch (Throwable throwable) {

throwable.printStackTrace();

}

} else {

Log.e(TAG, "重复点击已过滤...");

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值