Android面向切面AspectJ

        这一节主要了解一下AspectJ技术,它属于AOP(Aspect Oriented Programming)技术,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。最先是应用在Java后端,如Spring,在Android中一般应用场景如方法耗时,统计埋点,日志打印/打点;使用这个技术的原因是它能够降低代码耦合度,提高程序的可重用性,同时提高了开发的效率;

 AOP常用API:

@Aspect:声明切面,标记类
@Pointcut(切点表达式):定义切点,标记方法
@Before(切点表达式):前置通知,切点之前执行
@Around(切点表达式):环绕通知,切点前后执行
@After(切点表达式):后置通知,切点之后执行
@AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
@AfterThrowing(切点表达式):异常通知,切点抛出异常时执行

注:如果没有添加@Aspect,那么后面的注解一律不起作用

一般使用步骤如下:

1 项目下添加依赖
2 App下添加依赖
3 创建切面类
4 实现拦截业务
注:execution(<修饰符><返回类型><包.类.方法(参数)><异常>) //修饰符和异常可以省略

栗子:

项目下gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.aspectj:aspectjtools:1.8.9'
        classpath 'org.aspectj:aspectjweaver:1.8.9'
    }
}
app下gradle:

implementation 'org.aspectj:aspectjrt:1.8.9'


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;
            }
        }
    }
}
import android.util.Log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class CheckAspectJ {
    private static final String TAG = "CheckAspectJ";

    @Pointcut("execution(* *.test())")
    public void pointcut() {
        Log.i(TAG,"@pointcut");
    }
// Log.i(TAG,

    @Before("pointcut()")
    public void before(JoinPoint point) {
        Log.i(TAG,"@Before");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        Log.i(TAG,"@Around");
        joinPoint.proceed();
        Log.i(TAG,"@Around----->>> end");
    }

    @After("pointcut()")
    public void after(JoinPoint point) {
        Log.i(TAG,"@After");
    }

    @AfterReturning("pointcut()")
    public void afterReturning(JoinPoint point, Object returnValue) {
        Log.i(TAG,"@AfterReturning returnValue="+returnValue
                +"  point = "+point);
    }

//    @AfterThrowing(value = "pointcut()", throwing = "ex")
//    public void afterThrowing(Throwable ex) {
//        Log.i(TAG,"@afterThrowing");
//        Log.i(TAG,"ex = " + ex.getMessage());
//    }

    @AfterThrowing(value = "pointcutThreadTest()", throwing = "ex")
    public void afterThrowing(Throwable ex) {
        Log.i(TAG,"@afterThrowing");
        Log.i(TAG,"ex = " + ex.getMessage());
    }

    @Pointcut("execution(* com.sky.aopshow.MainActivity.threadTest())")
    public void pointcutThreadTest() {
    }
    @Around("pointcutThreadTest()")
    public void calculateFunctionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        Log.i(TAG,"pointcut1 ---------calculateFunctionTime---------@Around");
        long beginTime = System.currentTimeMillis();
        joinPoint.proceed();
        long endTime = System.currentTimeMillis();
        Log.i(TAG,"pointcut1 -----------calculateFunctionTime-------运行时间:" + (endTime - beginTime));
    }
  private void initView() {
        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);
        button3 = findViewById(R.id.button3);
        button4 = findViewById(R.id.button4);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                test();
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               threadTest();
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stepOn1();
                stepOn2("小明");
                stepOn3("小明", 18);
            }
        });
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                CheckAspectJ.isLoagin = !CheckAspectJ.isLoagin;
            }
        });
    }

    public void test() {
         Log.i(TAG,"Hello,Decard Terminal...");
    }

    private void stepOn1() {
         Log.i(TAG,"stepOn1");
    }

    private void stepOn2(String name) {
         Log.i(TAG,"stepOn2");
    }

    private void stepOn3(String name, int i) {
         Log.i(TAG,"stepOn3");
    }


    public void threadTest() {
        System.out.println("Hello, AOP TANK");
        int a = 1 / 0;      
    }

原理:AspectJ意思是Java的Aspect java的AOP,它其实不是一个新的语言,它的核心ajc(编译器)\weaver(织入器);ajc编译器: 基于Java编译器之上的,它是用来编译.aj文件,aspectj在Java编译器的基础上增加了一些它自己的关键字和方法。因此,  ajc也可以编译Java代码。weaver织入器:为了在Java编译器上使用AspectJ而不依赖于Ajc编译器,aspectJ5 出现了@AspectJ,使用注释的方式编写AspectJ代码,可以在任何Java编译器上使用;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值