Android使用AspectJ

一、基本介绍

1. AOP

在了解AspectJ前,我们首先了解另外一个名词:AOP

1.1 概念

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,它可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。

1.2 作用

AOP可以做什么呢?举个例子,android中容易发生View被连续点击的情况,正常我们可以在某个view的onClick事件中记录上一次点击的时间点然后进行对比,在1s内的多次点击就被忽略掉。但是,先不说整个应用,某个界面上可点击的view就有那么多,我们要为每一个view的onClick都增加同样的处理逻辑么?AOP就可以帮我们进行统一处理。

1.3 实现方式

AOP实现主要分为 静态 和 动态 两种

  • 静态方式:在编译期,切面直接以字节码方式编译到目标字节码文件中,生成静态的AOP代理类(主要有:AspectJ等)
  • 动态方式:在运行期,为接口动态生成代理类(主要有:Spring AOP、动态代理、自定义类加载器等)

2. AspectJ

理解完AOP,我们再来看AspectJ官方progguide

2.1 概念

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。简单来说,AspectJ是AOP的一种实现框架。

2.2 使用

AspectJ是在编译期通过特殊的编译器(ajc)在不改变代码的前提下织入代码。所以我们有必要了解下ajc官方文档。ajc通俗讲就是AspectJ编译器,在上方文档可以看到,可以进行一系列的参数配置。

二、基本使用

1. 以Gradle的Plugin形式使用

gradle的plugin创建方式也有多种,# Developing Custom Gradle Plugins:

  • Build script
  • buildSrc project
  • Standalone project

后续我会单独一篇文章详细介绍,这里只使用Standalone project的方式介绍AspectJ的使用

1.1 创建Android module:libplugin

创建一个Android Library,然后删除掉不必要的java文件夹、Androidmanifest.xml等文件。由于插件使用groovy编写,所以删掉java,重新创建groovy文件夹。

1.2 修改build.gradle

plugins {
    // 使用的是groovy
    id 'groovy'
}

dependencies {

    implementation gradleApi()//gradle sdk
    implementation localGroovy()//groovy sdk
    implementation 'org.aspectj:aspectjtools:1.8.1'
}


// 用于发布该插件,其他工程可通过配置引用
apply plugin: 'maven-publish'
repositories {
    google()
    jcenter()
    mavenCentral()
}

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.java
                groupId = 'com.king.plugin'
                artifactId = 'AspectJPlugin'
                version = '1.0.0'
            }
        }

        repositories {
            maven {
                allowInsecureProtocol true
                // 指定发布的位置为当前工程的repo目录下
                url = uri('../repo')
            }
        }
    }
}

1.3 编写插件

继承org.gradle.api.Plugin,在apply编写逻辑

public class AspectJPlugin implements Plugin {

    @Override
    void apply(Project project) {
        project.dependencies {
            implementation 'org.aspectj:aspectjrt:1.8.9'
        }
        project.android.applicationVariants.all { variant ->
            def javaCompile = variant.javaCompile
            javaCompile.doLast {
                String[] args = ["-showWeaveInfo",
                                 "-1.8",
                                 "-inpath", javaCompile.destinationDir.toString(),
                                 "-aspectpath", javaCompile.classpath.asPath,
                                 "-d", javaCompile.destinationDir.toString(),
                                 "-classpath", javaCompile.classpath.asPath,
                                 "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]

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

1.4 创建properties文件,关联插件

具体文件结构如下图所示

1.5 构建发布

在gradle功能区展开,可以看到libplugin下边有个publish的task,双击运行

就会在AspectJDemo目录下生成repo文件夹,并生成了相应的插件

1.5 app module中使用该插件

在项目的build.gradle配置上方生成的插件

buildscript {
    repositories {
        google()
        // 配置插件路径
        maven {
            url('repo')
        }
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.3"
        // 配置插件
        classpath "com.king.plugin:AspectJPlugin:1.0.0"
        classpath "org.aspectj:aspectjrt:1.8.9"
    }
}

allprojects {
    repositories {
        google()
        maven {
            url('repo')
        }
        mavenCentral()
    }
}

在app module 的build.gradle使用该插件

plugins {
    id 'com.android.application'
}
// 使用插件
import com.king.plugin.AspectJPlugin
apply plugin: AspectJPlugin
}

dependencies {
    ...
    implementation 'org.aspectj:aspectjrt:1.8.9'
}

1.6 总结

至此,你已经可以正常的在项目中使用aspectj了~这里主要介绍aspectj的使用,所以不详细介绍上边的禁止view频繁点击demo,具体代码在gitee: Demo下载地址

2. 直接使用别人写好的aspectj plugin

上述的步骤挺繁琐,所以有人专门写好了相应的插件:gradle_plugin_android_aspectjx

主要的使用流程如下:

2.1 项目build.gradle配置

buildscript {
    ...
    dependencies {
        ...
        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8'
    }
}

2.2 app module的build.gradle配置

apply plugin: 'android-aspectjx'

// 配置需要编译包含的文件
aspectjx {
    include 'com.king'
    // exclude:排除
}

// aspectjx的开关,默认为true
aspectjx {
    enabled true
}

2.3 总结

至此,已经可以正常在项目中使用aspectj了~相比起来,会比上边的方法方便很多。稍后再添加上这个相应的demo

文章来源于互联网:Android使用AspectJ

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/21129,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?