Android 利用 AOP 对点击事件作防抖处理

Header

最近项目中有一个需求,需要对重复的点击事件作过滤处理。

可能第一个想到的方法是在 OnClickListener.onClick 中根据时间间隔来判断,这也是比较传统的方案。但是缺点同样也很明显,就是对现有代码的侵入性太强了。因为点击事件回调的代码我们早已写好了,现在再去改动会很痛苦,并且改动的范围也很广。

那么有没有一种方法是不需要改动源代码,就可以实现对点击事件去重的呢?当然有,我们可以利用 AOP 来实现一套方案。接下来就来讲讲这套方案就具体实现。

Body

在写代码之前,需要先设置 AOP 的配置,AOP 一般采用的是 AspectJ 。而在 Android 中一般直接使用 hugo 或者 gradle_plugin_android_aspectjx 插件,这样就省去了配置 AspectJ 的麻烦。在这里我使用的就是 gradle_plugin_android_aspectjx 插件,gradle_plugin_android_aspectjx 具体的配置就不详细展开了,可以自行去了解。

阅读更多

Android 使用 OpenCV 对图片进行二值化和去燥处理

最近做的项目中有使用到 OpenCV ,并且利用了 OpenCV 对图片做一些简单的处理。所以今天打算记录一下一些常用的 OpenCV 操作。

以下的 OpenCV 代码都是基于 OpenCV v3.3.0 aar 版本

二值化

所谓的二值化,就是将图片上的像素点的灰度值设置为0或255,也就是将整个图片呈现出明显的只有黑和白的视觉效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static Bitmap binarization(Bitmap bitmap) {
// 创建一张新的bitmap
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Mat origin = new Mat();
Mat gray = new Mat();
Mat out = new Mat();
Utils.bitmapToMat(bitmap, origin);
Imgproc.cvtColor(origin, gray, Imgproc.COLOR_RGB2GRAY);
// 二值化处理
Imgproc.adaptiveThreshold(gray, out, 255.0D, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 25, 10.0D);
Utils.matToBitmap(out, result);
origin.release();
gray.release();
out.release();
return result;
}
阅读更多

Android ARouter 源码解析(五)

arouter-gradle-plugin version : 1.0.2

AutoRegister : https://github.com/luckybilly/AutoRegister

前言

在本系列的第一篇中讲过,ARouter 可以通过扫描 dex 文件中 class 的全类名,来加载 compiler 生成的路由类。但这种方式影响性能,并且效率也不高。所以在 ARouter v1.3.0 之后的版本中,加入了自动注册的方式进行路由表的加载,自动注册可以缩短初始化时间,解决应用加固导致无法直接访问 dex 文件从而初始化失败的问题。

阅读更多

Android ARouter 源码解析(四)

arouter-compiler version : 1.2.2

前言

之前对 arouter-api 做了整个流程的分析,今天来看看 arouter-compiler 。

arouter-compiler 主要是利用 apt 在编译期自动生成代码的。之前我们看到的 ARouter$$Root$$appARouter$$Group$$testTest1Activity$$ARouter$$Autowired 等都是 arouter-compiler 生成的。

阅读更多

Android ARouter 源码解析(三)

arouter-api version : 1.4.1

前言

到现在为止,ARouter 还有最后的依赖注入还没有解析过,那么今天就来深入探究一下其实现原理。

PS : 因为依赖注入的原理还比较简单,所以本篇篇幅会较短。

@Autowired解析

想要用 ARouter 实现依赖注入,需要在 Activity/Fragment 中加上

阅读更多

ARouter 源码解析(二)

前言

前几天对 ARouter 的页面跳转源码进行了分析,趁着今天有空,就讲讲 ARouter 里面的拦截器吧。

拦截器解析

把视线转移回 ARouter 的 init 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void init(Application application) {
if (!hasInit) {
logger = _ARouter.logger;
_ARouter.logger.info(Consts.TAG, "ARouter init start.");
hasInit = _ARouter.init(application);
// 如果初始化完成了
if (hasInit) {
_ARouter.afterInit();
}

_ARouter.logger.info(Consts.TAG, "ARouter init over.");
}
}
阅读更多

Android ARouter 源码解析(一)

前言

之前对 ActivityRouter 的源码做了一次分析,相信大家对路由框架已经有一个大概的理解了。

而今天给大家分析一下 ARouter 。大家在项目组件化的过程中,可能绝大多数的开发者都会使用 ARouter 来作为项目的路由框架。毕竟 ARouter 是阿里出品,优点自然不必多说了。

所以在平常使用的过程中,不仅仅要做到会用,还要深入了解一下 ARouter 的内部原理。

本次 ARouter 的解析分为三部分:

  1. 对 IRouteRoot 页面跳转进行源码解析;
  2. 对 IInterceptorGroup 拦截器进行源码解析;
阅读更多

Android ActivityRouter 源码解析

Header

在如今的 Android 组件化开发中,一款好的路由框架是不可或缺的。比如目前阿里的 ARouter 、美团的 WMRouter 等。路由框架可以降低 Activity 之间的耦合,从而在不需要关心目标 Activity 的具体实现类, 利用协议完成跳转。

ActivityRouter使用方法

在AndroidManifest.xml配置

阅读更多

Android Architecture Component ViewModel 解析

Header

之前给大家分析过了 LiveData ,今天就来看看 ViewModel 。

ViewModel 的作用就相当于 MVP 中的 Presenter ,是用来衔接 Model 和 View 的。通常把一些与 View 无关的业务逻辑写在 ViewModel 里面。ViewModel 内部创建出 LiveData 对象,利用 LiveData 对象来传递数据给 View 。

ViewModel 相对于 Presenter 而言,有以下几个好处:

  1. ViewModel 并不直接持有 View ,所以在 ViewModel 销毁时不需要像 Presenter 一样地去手动解除 View 的绑定,也就不会造成持有 View 导致的内存泄漏;
阅读更多

Android Architecture Component Lifecycle 解析

Header

Lifecycle 的作用简单的来说就是让你自己定义的东西可以感知生命周期。比如你想设计了一个 GPS 位置监听器,打算在 Activity 可交互状态下发送地址位置,那么就可以利用 Lifecycle 来做这件事,这样和 Activity 的耦合性就减少了很多。

Lifecycle

Part 1

LifecycleOwner

先来看 LifecycleOwner 接口,这个接口定义就说明了某样东西是具有生命周期的。getLifecycle() 方法返回生命周期。

阅读更多