android AOP 编程之aspectj实战笔记

背景

现在一提到aspectj,大家都是想到aspectjx这个别人封装好的插件,确实也很好用,只要在项目下grade文件添加下面几行代码就可以了:

 classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8' //project的bulid.gradle
 apply plugin: 'android-aspectjx'  // 使用 AspectJX 插件 module 的bulid.gradle
 api 'org.aspectj:aspectjrt:1.8.13' //在依赖里面        module 的bulid.gradle

然后就可以美滋滋的写aspect切面文件了
*但是对于android library(不是一个app)这种情况,这个插件是不适用的,因为里面规定了只扫描编译成app的class *
所以我使用了原生的aspectj来完成这种情况的注入,鉴于现在查到的资料都比较老,所以写一下这个笔记给有需要的人,也防止我忘了,本文章不涉及有关知识的讲解仅仅是操作,详细了解可以看后面的链接(或者哪天有空更新下,大概)。

一 操作步骤

(1) 配置环境

  1. 在project的build.grade添加依赖
classpath 'org.aspectj:aspectjweaver:1.9.4'
  1. module 的bulid.gradle添加以下代码
implementation 'org.aspectj:aspectjrt:1.8.13' //依赖里面

//然后找个下面空的地方复制下面的代码进去,下面的代码主要是替换成ajc编译器,
//android.libraryVariants.all表示会
//扫描android library的class,就是这里让注入第三方库可以成功
//如果是想扫描app的换成android.applicationVariants.all
//
apply plugin: 'com.android.library' //如果没有记得加上这句

import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
final def log = project.logger

android.libraryVariants.all{ variant ->

    JavaCompile javaCompile = variant.javaCompiler
    javaCompile.doLast {
        String[] args = ["-showWeaveInfo",
                         "-1.8",
                         "-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) 写切面文件

aspect 切面

在编译时,由编译器把切面调用编译进字节码,这种方式需要定义新的关键字并扩展 编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入。所以第一步要做的就是新建一个java文件,在类名上面加上注解@aspect,这表示这是一个切面文件,ajc编译器会识别这个注解按照规则进行代码的织入。类似下面:

@Aspect  //①
public class MethodAspect {

    @Pointcut("call(* com.wandering.sample.aspectj.Animal.fly(..))")//②
    public void callMethod() {
    }

    @Before("callMethod()")//③
    public void beforeMethodCall(JoinPoint joinPoint) {
        Log.e(TAG, "before->" + joinPoint.getTarget().toString()); //④
    }
}

piontcut 切点

如上图的这行代码就定义了一个切点

@Pointcut("call(* com.wandering.sample.aspectj.Animal.fly(..))")//②

具体怎么定义还是上github上大神总结的规则
Pointcut语法
Pointcut语法
Pointcut语法
在这里插入图片描述

advice

advice语法

总结

AOP是Aspect Oriented Programming,即面向切面编程。OOP:Object Oriented Programming,面向对象编程。OOP的主要功能是数据封装、继承和多态,而AOP提供了一种新的视角,AOP把系统分解为不同的关注点,或者称之为切面(Aspect),如打印日志,权限检查等都可以使用AOP方式让代码更加简洁,业务代码更加明确。

参考文章

Android AspectJ详解
AOP面向切面编程,AspectJ在Android中应用二三事(上)
AspectJ In Android Studio
原生aspectj原理解析
sample_aspectj

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值