Android中埋点的AOP

439 阅读1分钟

埋点问题

相关介绍:www.jianshu.com/p/705a2f9f8…

几种实现AOP的方式

相关介绍:blog.csdn.net/u010072711/…

AOP的实现之APT

相关介绍:blog.csdn.net/asialiyazho…

AOP的实现之AspectJ

相关介绍:www.jianshu.com/p/5f869930e…

AOP: Aspect Oriented Programming 面向切面编程。
AOP是个概念,AspectJ 是它的一个具体实现(Java)。

AspectJ:一个实现AOP的框架,核心是他的编译器(ajc)。就做了一件事,将 AspectJ 的代码在编译期插入到目标程序中。运行时没啥区别。
ajc 会构建目标程序和AspectJ 代码的联系,在编译期将 AspectJ 代码插入指定的 PointCut中。达到AOP的目的。

build.gradle配置

 dependencies {
        classpath 'org.aspectj:aspectjtools:1.8.10'
        classpath 'org.aspectj:aspectjweaver:1.8.10'
    }

app.gradle配置

dependencies {
  implementation 'org.aspectj:aspectjrt:1.8.10'
}
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main

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.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
            }
        }
    }

确定切面的功能

@Aspect
public class CheckLoginAspect {

    /**
    * 指定切点位置
    * 通配符确定切点
    */
    @Pointcut("execution(* com.package.name.xxxFunctionActivity.doSomeThing(..))")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint point) {
        Log.e("Mr.S", "@Before");
    }
    
    //注意 如果不调用joinPoint.proceed() 此方法不调用
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        CheckLogin checkLogin = signature.getMethod().getAnnotation(CheckLogin.class);
        
        if (checkLogin != null) {//通过注解来标记需要检查的地方
            if (isLogin()) {
                Log.e("Mr.S", "@Around" + "--" + "登录成功");
                return joinPoint.proceed();
            } else {
                Log.e("Mr.S", "@Around" + "--" + "请登录");
                Login((Context) joinPoint.getThis());
                return null;//注意这里的返回值,将会替代该方法的返回值
            }


        }
        return joinPoint.proceed();
    }

    @After("pointcut()")
    public void after(JoinPoint joinPoint) {
        Log.e("Mr.S", "@After");
    }

    @AfterReturning(value = "pointcut()", returning = "returnValue")
    public void afterReeturning(JoinPoint joinPoint, Object returnValue) {
        Log.e("Mr.S", "@AfterReturning" + "--" + returnValue);
    }

    @AfterThrowing(value = "pointcut()", throwing = "throwable")
    public void afterThrowing(Throwable throwable) {
        Log.e("Mr.S", "@AfterThrowing" + "--" + throwable.getMessage());
    }