Android AOP基本用法全面详解

 更新时间:2023年09月12日 11:50:46   作者:搬砖的兔子  
这篇文章主要为大家介绍了Android AOP基本用法全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

什么是AOP

AOP(Aspect Oriented Programming)意为面向切面编程,指通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

其广泛的应用在代码的后期修改与维护之中,它对原代码侵入性少,容易扩展辅助功能,可以使原执行逻辑与改变执行逻辑解耦。

现在有一个智能门,以前的开门的逻辑是:输入密码 -> 拎动把手 -> 开门,现在呢业主觉得密码有可能被盗,不够安全,希望加上指纹验证。这时候我们只需要将 验证指纹 这一步插入到 开门 之前就完成了,现在的逻辑是:输入密码 -> 拎动把手 -> 指纹验证 -> 开门。这种思维就是一种面向切面的思维。

什么是AspectJ

要知道AOP只是一种编程思想,那么,在android中,我们该通过何种工具来实现这种思想呢,没错,就是AspectJ。要掌握AspectJ首先要明确下面的几大概念:

Advice(通知):定义需要被注入到.class字节码文件中的代码,通俗点儿来说就是告诉编织器哪里是你需要插入的代码。

  • @Pointcut :定义切点、标记方法以便于重用。
  • @Before :前置通知,其内容在切点之前执行。
  • @Around :环绕通知,其内容贯穿整个切点前后。
  • @After:后置通知,其内容在切点之后执行。
  • @AfterReturning:返回通知,其内容在切点返回结果后再执行。
  • @AfterThrowing:异常通知,其内容在切点抛出异常时执行。

JoinPoint(连接点):即允许你插入代码的地方。

Pointcut(切入点):是对连接点的筛选与定义的一种表达式。

  • 如下图所示,"execution(* android.view.View.OnClickListener.onClick(..))"是一个完整的切点表达式,它是由execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)组成的,其中<修饰符模式>和<异常模式>可以省略。

Aspect(切面):切面是通知和切入点的结合。

Weaving(织入):这个很好理解就是把我们定义好的切面注入到目标对象中去的过程。

基本用法

插件配置

//在根build.gradle下配置:
dependencies {
    ...
    classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8' 
}
//在app/build.gradle下配置
apply plugin: 'com.hujiang.android-aspectjx'
aspectjx {
    //关闭AspectJX功能
    enabled true
    //织入遍历符合条件的库
    //includeJarFilter 'universal-image-loader', 'AspectJX-Demo/library'
    //排除包含‘universal-image-loader'的库
    //excludeJarFilter 'universal-image-loader'
}

定义切面

创建一个类,并通过@Aspect定义为一个切面。

@Aspect
public class AspectTest {
    ......
}

创建通知、添加切点表达式

在该类中添加需要编织的方法,并通过通知和切点表达式来定义它。Ok,一个简单的防抖的OnClick判断就切入到你的程序中去了。相信其他业务你也能很好的利用AspectJ来处理了。

@Aspect
public class AspectTest {
    private static final String TAG = "AspectTest";
    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickListener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        Log.d(TAG, "onClick");
        if (!NoDoubleClickUtils.isDoubleClick()){
            proceedingJoinPoint.proceed();    //切回到切点并执行后续代码
        }
    }
}

补充:第三方库兼容

有时候我们在使用AspectJ的时候可能会遇到引入了一些其他的三方库的情况,而我们又需要对其内的连接点进行编织、切入。如上述点击事件防抖的例子,可能用到了Butterknife来注解@onClick(),这时你会发现上述切入表达式不起作用了,为什么呢,我们看一下Butterknife中的@OnClick定义就知道了。

@Target(METHOD)
@Retention(RUNTIME)
@ListenerClass(
    targetType = "android.view.View",
    setter = "setOnClickListener",
    type = "butterknife.internal.DebouncingOnClickListener",
    method = @ListenerMethod(
        name = "doClick",
        parameters = "android.view.View"
    )
)
public @interface OnClick {
  /** View IDs to which the method will be bound. */
  @IdRes int[] value() default { View.NO_ID };
}

我们可以发现。其通过Annotation Processor对@OnClick进行扫描,并将android.view.View.OnClickListener.onClick方法替换为butterknife.internal.DebouncingOnClickListener.doClick方法。因此为了兼容ButterKnife上述切入点表达式应该改为如下方式,及对butterknife的OnClick方法进行切入。

@Around("execution(* android.view.View.OnClickListener.onClick(..)) || execution(@butterknife.OnClick * *(..))")
public void onClickListener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
    Log.d(TAG, "onClick");
    if (!NoDoubleClickUtils.isDoubleClick()){
        proceedingJoinPoint.proceed();
    }
}

以上就是Android AOP基本用法全面详解的详细内容,更多关于Android AOP基本用法的资料请关注脚本之家其它相关文章!

相关文章

  • Android源码学习之观察者模式应用及优点介绍

    Android源码学习之观察者模式应用及优点介绍

    定义对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新等等,需要了解的朋友可以参考下
    2013-01-01
  • Android sqlite设置主键自增长的方法教程

    Android sqlite设置主键自增长的方法教程

    这篇文章主要给大家介绍了关于Android sqlite设置主键自增长的方法教程,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • Android使用 Coroutine + Retrofit打造简单的HTTP请求库

    Android使用 Coroutine + Retrofit打造简单的HTTP请求库

    这篇文章主要介绍了Android使用 Coroutine + Retrofit打造简单的HTTP请求库,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下
    2021-03-03
  • Android使用setContentView实现页面的转换效果

    Android使用setContentView实现页面的转换效果

    这篇文章主要介绍了Android如何使用setContentView实现页面的转换效果,帮助大家更好的利用Android进行开发,感兴趣的朋友可以了解下
    2021-01-01
  • Android使用RecyclerView实现水平滚动控件

    Android使用RecyclerView实现水平滚动控件

    这篇文章给大家介绍了利用Android使用RecyclerView实现水平滚动的效果,本文做了一个年龄滚动控件的例子,对大家开发Android具有一定参考借鉴价值,有需要的可以参考借鉴。
    2016-09-09
  • Android图片压缩的实例详解

    Android图片压缩的实例详解

    这篇文章主要介绍了Android图片压缩的实例详解的相关资料,android图片压缩主要有两种方式:压缩图片分辨率与压缩图片质量,需要的朋友可以参考下
    2017-08-08
  • android使用surfaceview+MediaPlayer播放视频

    android使用surfaceview+MediaPlayer播放视频

    这篇文章主要为大家详细介绍了android使用surfaceview+MediaPlayer播放视频,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Android性能优化之线程监控与线程统一详解

    Android性能优化之线程监控与线程统一详解

    这篇文章主要为大家介绍了Android性能优化之线程监控与线程统一详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 浅谈谈Android 图片选择器

    浅谈谈Android 图片选择器

    近段时间有项目要求写一个类似于微信发送图片时,用来选择照片的一个图片浏览器。相信有很多网友也有这样的需求,这里分享给大家
    2015-12-12
  • Android 夜间模式的实现代码示例

    Android 夜间模式的实现代码示例

    本篇文章主要介绍了Android 夜间模式的实现代码示例,实现能够根据不同的设定,呈现不同风格的界面给用户,有兴趣的可以了解一下。
    2017-03-03

最新评论