AndroidStudio中 AspectJ 基础使用 简介

AOP(Aspect Oriented Programming)切面编程在处理一些与业务逻辑无关,但在很多地方又不得不添加相关逻辑代码,可以很好的解决相关问题,比如在Android中有些地方需要打LOG日志,或者在某些地方需要检查系统权限等,可以很好的解决这类问题。

而AOP中主要使用的就是AspectJ,AspectJ有自己相关的一套语法,大致和JAVA类似。官方简介

那么在AndroidStudio 中要怎么使用AOP呢?

首先需要新建一个module,方便引入相关的AspectJ配置,便于在其中编写与业务逻辑无关紧要,并且在代码中经常出现的常用代码,
之后在module下的build.gradle中 导入AspectJ的dependences

compile ‘org.aspectj:aspectjrt:1.8.9’

并在build.gradle根下配置

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'org.aspectj:aspectjtools:1.8.9'
        classpath 'org.aspectj:aspectjweaver:1.8.9'
    }
}

android.libraryVariants.all { variant ->
    LibraryPlugin plugin = project.plugins.getPlugin(LibraryPlugin)
    JavaCompile javaCompile = variant.javaCompile
    javaCompile.doLast {
        String[] args = ["-showWeaveInfo",
                         "-1.5",
                         "-inpath", javaCompile.destinationDir.toString(),
                         "-aspectpath", javaCompile.classpath.asPath,
                         "-d", javaCompile.destinationDir.toString(),
                         "-classpath", javaCompile.classpath.asPath,
                         "-bootclasspath", plugin.project.android.bootClasspath.join(
                File.pathSeparator)]

        MessageHandler handler = new MessageHandler(true);
        new Main().run(args, handler)

        def log = project.logger
        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:
                case IMessage.INFO:
                    log.info message.message, message.thrown
                    break;
                case IMessage.DEBUG:
                    log.debug message.message, message.thrown
                    break;
            }
        }
    }
}

以上module的build.gradle 配置主要是搭建AspectJ运行环境

之后在app下的build.gradle添加module的依赖,并且添加如下配置

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.aspectj:aspectjtools: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.5",
                         "-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;
            }
        }
    }
}

以上配置主要是将app和module关联起来。

然后在module中创建TestAspectJ类,
具体代码如下:

package com.clayx.org.aspectj;

import android.annotation.TargetApi;
import android.os.Build;
import android.util.Log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/**
 * Created by Administrator on 2016/9/2.
 */
@Aspect
public class TestAspectJ {

    private static final String METHOD_EXECUTION = "execution(* *..MainActivity+.onCreate(..))";

    private static final String METHOD_CALL = "call(* *..MainActivity+.test(..)) && args(name)";

    private String TAG = "Clayx";

    @Pointcut(METHOD_EXECUTION)
    public void methodExecution() {
    }

    @Pointcut(METHOD_CALL)
    public void methodCall(String name) {

    }

    @Around("methodExecution()")
    public void aroundMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        joinPoint.proceed();
        String result = "-----------------------------MethodExecution";
        Log.e(TAG, result);
    }

    @Around("methodCall(String)")
    public Object arouneMethodCall(ProceedingJoinPoint joinPoint){
        String name = (String) joinPoint.getArgs()[0];
        Log.e(TAG,name);
        return name;
    }

}

运行APP,打印出Log如下:

对于注解的使用,可以更好的和AspectJ结合使用,

注解类如下:

package com.clayx.org.aspectj.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by Administrator on 2016/9/2.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAspectJ {

}

注解相关的AspectJ的实现类

package com.clayx.org.aspectj.anno;

import android.content.Context;
import android.widget.Toast;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/**
 * Created by Administrator on 2016/9/2.
 */

@Aspect
public class TestAspect {

    @Pointcut("execution(@TestAspectJ private * *..*.*(..))")
    public void testAspect() {

    }

    @Around("testAspect()")
    public void testTestAspect(ProceedingJoinPoint joinPoint) {

        Toast.makeText((Context) joinPoint.getTarget(), "OK", Toast.LENGTH_SHORT).show();

    }

}

注解运行如下:

代码下载地址

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值