您的位置:首页 > 移动开发 > Android开发

AOP In Android (2)——基础实战

2018-02-24 11:01 169 查看

0.前言

本文基于上一篇上一篇的初步认识,进行一个简单的AOP实现。

本文目的:

AOP在android中的初步实践

Thanks:

主要参考

浅谈Android面向切面编程(AOP):

https://www.jianshu.com/p/aa1112dbebc7

该作者的gayhub:

https://github.com/GitLqr/AndroidAopDemo

其他资料

详解JDK 5 Annotation 注解之@Target的用法介绍

http://blog.csdn.net/snakemoving/article/details/74364351

@Retention注解

http://blog.csdn.net/asdgbc/article/details/70196749

1.集成AspectJ

app/build.gradle 内 添加(注意最顶上的import语句。):

...
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.aspectj:aspectjtools:1.8.1'
}
}

repositories {
mavenCentral()
}

android {
...
}

dependencies {
...
compile 'org.aspectj:aspectjrt:1.8.1'
}

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


2.定义一个自定义注解

package aroutertest.zj.com.zjaop.aspectj;

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

@Target({ElementType.METHOD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckLogin {

}


3.定义一个Aop切面

package aroutertest.zj.com.zjaop.aspectj;

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;

/**
* Created by thinkpad on 2018/2/8.
*/

@Aspect public class CheckLoginAspectJ {

String TAG = "CheckLoginAspectJ___";

//    aroutertest.zj.com.zjaop.aspectj.CheckLogin
//    * *(..)) 代表可以处理CheckLogin这个类所有的方法
@Pointcut("execution(@aroutertest.zj.com.zjaop.aspectj.CheckLogin * *(..))")
public void handleMethod() {
System.out.println(TAG + "@handleMethod");
}

@Before("handleMethod()")
public void before(JoinPoint point) {
System.out.println(TAG + "@Before");
}

@Around("handleMethod()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(TAG + "@Around");
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        String name = signature.getName(); // 方法名:test
//        Method method = signature.getMethod(); // 方法:public void com.lqr.androidaopdemo.MainActivity.test(android.view.View)
//        Class returnType = signature.getReturnType(); // 返回值类型:void
//        Class declaringType = signature.getDeclaringType(); // 方法所在类名:MainActivity
//        String[] parameterNames = signature.getParameterNames(); // 参数名:view
//        Class[] parameterTypes = signature.getParameterTypes(); // 参数类型:View

//        TestAnnoTrace annotation = method.getAnnotation(TestAnnoTrace.class);
//        String value = annotation.value();
//        int type = annotation.type();

//        long beginTime = SystemClock.currentThreadTimeMillis();
joinPoint.proceed();
//        long endTime = SystemClock.currentThreadTimeMillis();
//        long dx = endTime - beginTime;
//        System.out.println("耗时:" + dx + "ms");
}

@After("handleMethod()")
public void after(JoinPoint point) {
System.out.println(TAG + "@After");
}

@AfterReturning("handleMethod()")
public void afterReturning(JoinPoint point, Object returnValue) {
System.out.println(TAG + "@AfterReturning");
}

@AfterThrowing(value = "handleMethod()", throwing = "ex")
public void afterThrowing(Throwable ex) {
System.out.println(TAG + "@afterThrowing");
System.out.println("ex = " + ex.getMessage());
}

}


4.添加测试代码

这俩方法是mainactivity内的俩按钮的点击事件。

@CheckLogin()
public void percheck(View view) {
System.out.println("Hello, I am 权限检查");
}

@CheckLogin()
public void logincheck(View view) {
System.out.println("Hello, I am 登录检查");
}


5.测试观察打印

点击按钮,输入如下。

I/System.out: CheckLoginAspectJ___@Before
I/System.out: CheckLoginAspectJ___@Around
I/System.out: Hello, I am 权限检查
I/System.out: CheckLoginAspectJ___@After
I/System.out: CheckLoginAspectJ___@AfterReturning


预警:

关于这个AspectJ,当我们定义了多个切点时,很有可能因为一个切点的表达式写错而导致编译出错,从而让其他的切点失效,所以玩的时候出错了的话,尽量将gradle consle打开。

6.Demo

https://github.com/zj614android/AopDemo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: