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相关文章推荐
- Spring AOP基础(Spring 3.x企业应用开发实战第六章)学习总结
- Android基础入门教程——8.3.2 绘图类实战示例
- 打好Android基础,实战中运用基础
- 真流弊、实战最真实的Android的切面编程 AOP
- 零基础Android手机嵌入式开发实战课程(网吧计费系统、多功能播放器、驱动开发)
- 【备忘】2016年黑马android安卓74期完整实战开发基础就业视频
- Android中的AOP编程之AspectJ实战实现数据埋点
- 零基础Android手机嵌入式开发实战教程的视频下载
- Android面向切面(AOP)编程实战
- 零基础Android开发实战视频教程
- 打好Android基础,实战中运用
- AOP In Android (1)——初识入门
- Android基础-- 利用handler发送消息报:"This message is already in use"解决办法
- Fragment在Android中的使用基础加实战
- Spring实战(第4版) Spring Inaction 笔记(第一章)依赖注入和AOP
- Android自定义UI实战(基础篇1)---组合控件封装
- AOP 之 AspectJ 全面剖析 in Android
- Android基于AOP的非侵入式监控之——AspectJ实战
- Android AOP基础
- 【备忘】2016年黑马android安卓74期完整实战开发基础就业视频