01AspectJ简介AspectJ是Java语言AOP(面向切面编程)的一种实现方案。AspectJ有两种实现方式,一种是使用Java语言和注解,然后通过AspectJ提供的编织器,编织代码到目标class文件。一种是直接使用AspectJ语言编写,然后使用ajc编译器用来编译aj文件,生成java标准的class文件。AspectJ语言的语法和Java一样,只是比Java语言多了一些关键字,但由于AndroidStudio并没有提供AspectJ语法的支持,所以在Android开发中使用AspectJ只能使用注解的方式来实现。02一些基本概念下面通过注解的实现方式来解释一些基本的概念:1. Aspect(切面)一个切面是一个独立的功能实现,一个程序可以定义多个切面,定义切面需要新建一个类并加上@Aspect注解。例如:SampleAspect就是一个切面 ,这个切面实现了打印所有Activity中OnCreate方法耗时的功能。@Aspect
public class SampleAspect{
@Pointcut("execution(void android.support.v4.app.FragmentActivity+.onCreate(..))")
public void activityOnCreate(){
@Around("activityOnCreate()")
public Object activityOnCreateTime(ProceedingJoinPoint joinPoint){
null;
long startTime = System.currentTimeMillis();
try {
catch (Throwable throwable) {
"chao","activityOnCreateTime:"+(System.currentTimeMillis() - startTime));
return object;<< 向右滑动查看完整代码 >>2. JointPoint(链接点)链接点代表了程序中可以切入代码的位置,包括函数的调用和执行,类的初始化,异常处理等,链接点就是利用AspectJ可以侵入修改的地方。例如Activity中onCreate方法的调用和执行,Activity的初始化,构造方法的执行等,可以在这些JointPoint(链接点)切入自己想要的代码。3. PointCut(切点)切点是具体的链接点,切点定义了需要织入代码的链接点,切点的定义有专门的语法。例如:下面这个就代表一个切点,这个切点表示了所有Activity以及其子类的onCreate方法的执行。@Pointcut("execution(void android.support.v4.app.FragmentActivity+.onCreate(..))")
public void activityOnCreate(){
<< 向右滑动查看完整代码 >>4. Advice(通知)通知代表对切点的监听,可以在这里编写需要织入的代码。通知包括:@Before方法执行前,@After方法执行后,@Around方法执行前后。例如:下面分别表示了切点activityOnCreate的执行前、执行后、执行前后的监听,其中@Around需要自己处理方法的执行,并且必须放在@Before和@After之前。@Around("activityOnCreate()")
public Object activityOnCreateTime(ProceedingJoinPoint joinPoint){
null;
long startTime = System.currentTimeMillis();
try {
catch (Throwable throwable) {
"chao","activityOnCreateTime:"+(System.currentTimeMillis() - startTime));
return object;
@Before("activityOnCreate()")
public void onCreateBefore(JoinPoint joinPoint){
"chao", "onCreateBefore" + joinPoint.getSignature().getDeclaringType() + ":" + joinPoint.getSignature().getDeclaringTypeName());
@After("activityOnCreate()")
public void onCreateAfter(JoinPoint joinPoint){
"chao", "onCreateAfter" + joinPoint.getSignature().getDeclaringType() + ":" + joinPoint.getSignature().getDeclaringTypeName());<< 向右滑动查看完整代码 >>03匹配表达式上面讲到了定义切点时需要用到专门的语法:匹配表达式。匹配表达式分为以下几种类型:1. 方法类型@Annotation] [public,protected,private] [static] [final] 返回值类型 [类名.]方法名(参数类型列表) [throws 异常类型]<< 向右滑动查看完整代码 >>
定义方法切点时需要用到方法类型的匹配表达式,其中execution()代表了方法的执行,[]中的内容为可选。
如果是构造方法只需要把方法名替换为new。例如:@Pointcut("execution(@com.sohu.aspectj.AspectLog public static final boolean)
public void activityIsFirst(){
@Pointcut("execution(public com.sohu.aspectj.KotlinClassFile.new(java.lang.String,boolean))")
public void kotlinClassInit(){<< 向右滑动查看完整代码 >>2. 运算符以及特殊符号!非 && 与 || 或//所有Fragment类以及其子类testParams方法的调用
@Pointcut("execution(public * testParams(..)) &&)
public void fragmentTestParams(boolean args,Fragment fragment){<< 向右滑动查看完整代码 >>+表示自身以及子类
*表示任意类型
..表示任意长度类型//AspectLog注解的在包com.sohu.aspectj开头的所有包下的方法
@Pointcut("execution(@com.sohu.aspectj.AspectLog * com.sohu.aspectj..*(..))")
public void fragmentaspectLog(Fragment fragment){<< 向右滑动查看完整代码 >>3. handler指定异常的处理//com.sohu.aspectj包开头下的所有Exception的异常
@Pointcut("handler(java.lang.Exception)&&within(com.sohu.aspectj.*)")
public void fragmentException(){
<< 向右滑动查看完整代码 >>4. 其它类型target是指切点所在的类的对象,只能是对象,例如:不能是target(android.support.v4.app.Fragment+)或者target(android.support.v4.app.*),只能是target(fragment)
with是指指定类中的所有链接点,可以包括包名和类名,例如:within(android.support.v4.app.Fragment+)或者within(android.support.v4.app.*)@Pointcut("execution(public * testParams(..)) && target(fragment) && args(args)"