面向切面编程(AOP)在Android中的应用

看完本篇文章你将学到什么? 1.基本了解AOP的编程思想,以及如何在Android中使用AOP的思想 2.借助AspectJ用AOP的思想实现埋点逻辑 3.借助AspectJ用AOP的思想实现屏蔽快速点击事件的处理

什么是AOP

AOP,字面翻译为面向切面编程。它是一种编程思想,不是什么新技术。可以这么理解,在Android开发过程中,我们经常会在我们的具体业务代码中加入全局性、系统性的与具体业务无关的代码。比如埋点、动态申请权限等等。AOP的思想就是将这些与业务无关的系统性的功能解耦出来,让代码看起来更清晰一点。使用AOP思想与正常程序流程的对比我们可以通过下面示例图片有个基础的认识:

上图1我们看到是我们正常的程序流程,程序的执行就像水从管道流出一样从上到下顺畅的纵向执行。图2为我们展示了AOP思想的程序执行流程,从图中可以看到我们的管道被从某一点横向的切开(AOP中将这个切点定义为pointCut),然后会在切入点植入一段我们在Aspect(类似于Java的类的理念,AOP中用来管理切点和执行代码块的一个概念)中定义的代码。示例仅是一种演示,实际情况是植入执行的代码块可以向被插入方法的前后同时植入代码块。目前实现AOP思想的框架有AspectJ、Spring、JBoss4.0等等。

AspectJ框架

为什么这里选择介绍AspectJ呢?主要是我公司的项目使用的是这个框架。那么什么是AspectJ?

它是实现AOP思想的一个框架,拥有自己的编译器和语法,可以在编译期间将需要植入的代码编译成Java代码插入到你的源代码文件当中。更直白点

我们的Android项目引用也非常的简单,2步就可以搞定:

  • 在项目的根目录的Build.gradle文件中加入下面的代码: 1dependencies { 2 classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0' 3}
  • 在你的app模块或者其他module中添加依赖: 1dependencies { 2 implementation 'org.aspectj:aspectjrt:1.8.9' 3}

应用

我们在项目中经常会遇到一个小问题,就是你对一个View绑定的一个点击事件用户疯狂的快速点击导致点击事件的处理代码被重复执行,常见的处理方式就是在点击事件中加入时间判断的逻辑,在短时间内的重复点击不做响应。但是如果有很多点击事件,这样处理起来显然让代码不好看。

所以,借助AspectJ中的AOP思想,可以在解决快速重复点击的问题的同时,可以让你的代码看的更优雅一点。

第一步:自定义一个注解
1@Retention(RetentionPolicy.RUNTIME)
2@Target(ElementType.METHOD)
3public @interface IgnoreFastClick {
4    long value() default 2000;
5}
第二步:写Aspect植入的类
 1@Aspect
 2public class IgnoreFastClickAspect {
 3
 4    int lastViewId=-1;
 5    long lastClickTime=0;
 6
 7    @Pointcut("execution(@com.bob.www.testdemo.aop.IgnoreFastClick * *(..))")
 8    public void hhh(){
 9    }
10
11    @Around("hhh()")
12    public void insertCodeBlock(ProceedingJoinPoint joinPoint) throws Throwable {
13        View view;
14        //取click方法中的参数view
15        if (joinPoint.getArgs() != null
16                && joinPoint.getArgs().length > 0
17                && joinPoint.getArgs()[0] instanceof View) {
18            view = ((View) joinPoint.getArgs()[0]);
19            if (view == null)
20                return;
21        } else {
22            return;
23        }
24
25        MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
26        Method method = methodSignature.getMethod();
27        if (method.isAnnotationPresent(IgnoreFastClick.class)) {
28            IgnoreFastClick ignoreFastClick = method.getAnnotation(IgnoreFastClick.class);
29            long nowTime = System.currentTimeMillis();
30            // 如果两次点击时间差小于或等于value的值,并且两次点击的是同一个View,就不执行onClick()方法
31            if (nowTime - lastClickTime <= ignoreFastClick.value()
32                    && view.getId() == lastViewId) {
33                Log.d("AOP", "you click is too fast!");
34            } else {
35                // 记住上一次点击的时间戳和View的ID
36                lastViewId = view.getId();
37                lastClickTime = nowTime;
38                执行onCLick()方法
39                joinPoint.proceed();
40            }
41        }
42    }
43}
第三步:给click事件方法加注解
 1    @Override
 2    protected void onCreate(Bundle savedInstanceState) {
 3        super.onCreate(savedInstanceState);
 4        setContentView(R.layout.activity_main);
 5
 6        mTestBtn = findViewById(R.id.btn_test);
 7        mTestBtn.setOnClickListener(new View.OnClickListener() {
 8
 9            @IgnoreFastClick
10            @Override
11            public void onClick(View v) {
12                Log.d("AOP", "----------------"+number++);
13            }
14        });
15    }

以后只要做防重点击的事件,只用加个注解就搞定了。

要想完全掌握AspectJ的语法还是挺多的,这里只是一个简单的抛砖引玉的例子哦。读者可以试试使用AspectJ完成事件统计相关的逻辑哦。讲的不好,仅供参考。

如果觉得本文对你有一点点的帮助,关注一下又能有什么损失呢?

原文发布于微信公众号 - 南京Android部落(nj_android)

原文发表时间:2018-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

SpringAop实现原理

SpringAop实现原理 什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Orien...

4684
来自专栏青玉伏案

设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)

在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern)。适配器模式用处还是比较多...

2048
来自专栏酷玩时刻

Android版-微信APP支付

服务端源码地址:http://git.oschina.net/javen205/weixin_guide 客户端源码地址:https://github.com...

1.1K2
来自专栏非著名程序员

Android中如何提取和生成mp4文件

随着Android 4.4及以上版本的逐渐普及,Android 4.1引入的MediaExtractor类,以及Android 4.3引入的MediaMuxer...

2867
来自专栏nnngu

02 浅析Spring的AOP(面向切面编程)

1、关于AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Program...

3457
来自专栏禁心尽力

总结切面编程AOP的注解式开发和XML式开发

       有段日子没有总结东西了,因为最近确实有点忙,一直在忙于hadoop集群的搭建,磕磕碰碰现在勉强算是能呼吸了,因为这都是在自己的PC上,资源确实有点...

25510
来自专栏向治洪

系统捕获异常并发送到服务器

大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个...

2087
来自专栏Android 开发学习

data-binding 踩坑记

2114
来自专栏向治洪

Android杀毒实现原理及实例

一个杀毒软甲最核心的部分一个是病毒库一个是杀毒引擎,病毒库从服务器中获得,杀毒引擎实际上是判断程序中的包名和签名是否匹配病毒库中的包名和签名,如果匹配则为病毒,...

2807
来自专栏流媒体

Android RTMP推流之MediaCodec硬编码一(H.264进行flv封装)

在前面Android平台下使用FFmpeg进行RTMP推流(摄像头推流)的文章中,介绍了如何使用FFmpeg进行H264编码和Rtmp推流。接下来讲分几篇文章来...

9013

扫码关注云+社区

领取腾讯云代金券