千家信息网

Android中如何实现切面编程

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容主要讲解"Android中如何实现切面编程",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android中如何实现切面编程"吧!安装AspectJA
千家信息网最后更新 2025年01月19日Android中如何实现切面编程

本篇内容主要讲解"Android中如何实现切面编程",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android中如何实现切面编程"吧!

安装AspectJ

Android上的ApsectJ开发由几部分组成,AspectJ gradle插件,ApsectJ依赖,还有 AspectJ编译器。
首先安装AspectJ编译器很简单,就跟安装JAVA环境一样,

下载链接:http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/aspectj-1.9.0.jar

目前最新的已经更新到1.9.1了。如果你电脑已经有JAVA环境的话直接运行这个jar包就行,
在安装完毕后需要配置环境变量到 aspectj的bin目录下,这里不赘述

export PATH="$PATH:~/Library/Android/sdk/platform-tools"export PATH="$PATH:/usr/local/opt/gradle/gradle-4.1/bin"export PATH="$PATH:~/Library/Android/sdk/ndk-bundle"export PATH="$PATH:~/Library/flutter/bin"export PATH="$PATH:~/Library/kotlinc/bin"export PATH="$PATH:~/Library/AspectJ/bin" <- AspectJ的PATH

配置完后运行 ajc -v 应该可以看到对应输出

AspectJ Compiler 1.9.0 (1.9.0 - Built: Monday Apr 2, 2018 at 18:52:10 GMT)

配置Android Gradle增加AspectJ依赖

构建带AspectJ支持的Android App的流程是先按正常流程编译出 .class 文件后,再用 ajc 编译器在 .class文件中插入我们需要的代码。

首先需要把 AspectJ 依赖加到 gradle根目录中,

buildscript {  repositories {    google()    jcenter()  }  dependencies {    classpath 'com.android.tools.build:gradle:3.1.2'    classpath 'org.aspectj:aspectjtools:1.8.9' //Aspect    classpath 'org.aspectj:aspectjweaver:1.8.9' //Aspect  }}

然后在项目app目录的build.gradle需要添加以下内容,

apply plugin: 'com.android.application'//+增加内容import org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Mainbuildscript {  repositories {    mavenCentral()  }  dependencies {    classpath 'org.aspectj:aspectjtools:1.8.9'    classpath 'org.aspectj:aspectjweaver:1.8.9'  }}repositories {  mavenCentral()}final def log = project.loggerfinal def variants = project.android.applicationVariantsvariants.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.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);  }}//-增加内容

这段gradle脚本是在java编译完成后追加一个 acj 的编译流程,

MessageHandler 是 AspectJ Tools中的对象,用来接收参数然后进行 acj 编译的。

最后再把 dependencies依赖加上对AspectJ的支持就可以了,

implementation 'org.aspectj:aspectjrt:1.9.0'

创建AspectJ代码

下面这部分代码看起来会一脸懵逼,不过目前先不用管具体的语法含义,

先跑起来环境,然后再结合理论慢慢在修改代码中感受就能快速的上手AOP了。

以一个HelloWorld为例子,我们的MainActivity中啥事情不干,只有基本的生命周期方法,

public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);  }  @Override  protected void onStart() {    super.onStart();  }  @Override  protected void onPause() {    super.onPause();  }  @Override  protected void onStop() {    super.onStop();  }  @Override  protected void onDestroy() {    super.onDestroy();  }}

现在我们要写一个AspectJ类,这个类看起来会跟一般的Java类有点不同,可以理解为它只是用注解作为媒介,让ACJ编译器知道要去注入哪些方法。

这个类要做的事情是告诉ACJ编译器,要在MainActivity中的每个方法前面打印一行log,输出当前执行的是哪个方法,

@Aspectpublic class AspectTest {  private static final String TAG = "AspectTest";  @Pointcut("execution(* phoenix.com.helloaspectj.MainActivity.**(..))")  public void executeAspectJ() {  }  @Before("executeAspectJ()")  public void beforeAspectJ(JoinPoint joinPoint) throws Throwable {    Log.d(TAG, "beforeAspectJ: injected -> " + joinPoint.toShortString());  }}

第一次接触AspectJ的看到这段代码有点摸不着头脑,解释一下几个注解的意思,

  • @Aspect: 告诉ACJ编译器这是个AspectJ类

  • @PointCut: PointCut是AspectJ中的一个概念,跟它一起的另一个概念是 JoinPoint,这两个概念一起描述要注入的切面

  • @Before: 表示要注入的位置,常用的有 Before/After/Around,分别表示在执行前,执行后,和取代原方法

这里@PointCut注解后的参数表示的意思是对 MainActivity中的所有方法进行注入,参数用的是正则匹配语法。
下面看看这段代码执行的结果

07-26 16:04:56.611 22823-22823/? D/AspectTest: beforeAspectJ: injected -> execution(MainActivity.onCreate(..))
07-26 16:04:56.661 22823-22823/? D/AspectTest: beforeAspectJ: injected -> execution(MainActivity.onStart())

看到虽然我们没有在MainActivity中写入log打印语句,但是通过AspectJ实现了,在MainActivity两个生命周期执行前插入了我们自己的log。

使用场景

AspectJ只是AOP的其中一种手段,类似的还有用 asm 去修改字节码。AOP之所以会有越来越多的人去了解,抽象上来说它可以非常好的去耦合。

高级点的可以用AOP来实现无痕埋点,数据收集,甚至修改SDK中动不了的代码。

到此,相信大家对"Android中如何实现切面编程"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

编译 代码 方法 编译器 内容 切面 环境 编程 参数 概念 注解 流程 配置 两个 事情 只是 周期 意思 文件 生命 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 为什么很多人觉得软件开发难 数据库表中可以有几个主键 永恒之塔怀旧服服务器状态查看 士兵网络安全犯罪心得体会 代还软件开发公司有哪些 一般管理系统共有的数据库表 服务器电源改成普通电源 软件开发具体学些什么 旧手机搭建服务器知乎 汤阴网络安全中心 用服务器跑代码创建虚拟环境 网络安全发展趋势毕业论文 南山区光纤网络技术开发厂家现货 3列数据找出相同的数据库 冠军之夜服务器崩溃视频 ice服务器加密码 点赞表数据库 汽车网络技术的发展历程 火妖服务器没人了 wow活跃的服务器 法治与网络安全手抄报三年级 上海欣腾互联网科技有限公司 服务器安全维护有哪些 济源软件开发公司 手机做服务器看视频 有关于互联网科技的知识 网络技术指什么意思 网络安全 互联网开放端口 软件开发专业的自我介绍 安防监控平台管理服务器
0