首页 > 编程语言 >【Android】Android AOP 编程框架

【Android】Android AOP 编程框架

时间:2024-08-22 12:52:32浏览次数:11  
标签:aop 编程 maven https AOP Android com android

什么是AOP编程

AOP编程全称Aspect Oriented Programming,面向切面编程

主要功能是在不改变原代码的前提下,对特点代码节点进行修改,预处理,后期处理

AOP的历史

Android的AOP编程框架比较多,它们大多具备以下特点

  • 以AspectJ为基础,提供AOP编程能力
  • AspectJ最早为Java项目中的编程框架,依赖于Maven插件实现
  • AspectJ的原理是在预编译期间,修改代码文件,生成代理对象,从而实现拦截效果
  • 通过Gradle插件,可以将AspectJ应用到Java和Kotlin项目
  • 但大多Gradle插件,依赖于Gradle版本,并且和Android的插件可能产生冲突
  • 因此大多Android Aspect Gradle Plugin,多年没人维护,不能在最新项目中使用
  • 因为Gradle和Android插件更新太频繁,并且不兼容旧代码,Aspect的适配工作工作量太大,很多作者都放弃维护了
io.freefair.aspectj

这个是我们今天要介绍的主角

相对于其它AOP框架,它的版本比较新,而且作者自身在使用,因此不用太担心维护问题

这个项目,没有依赖于其它库,是自己从零开始实现的,但支持了AspectJ的全部功能

其实依赖的库和插件越多,自身兼容性越容易出问题

引入插件依赖

这里用的是Gradle8.7+KotlinScript

settings.gradle.kts中输入以下代码

注意各个gradle插件的版本兼容性,这是gradle不可回避的一个问题

不过相信随着gradle越来越强大,功能越来越丰富,终究会有稳定下来的一天

pluginManagement {
    repositories {
        maven("https://maven.aliyun.com/repository/public/")
        maven("https://maven.aliyun.com/repository/central/")
        maven("https://maven.aliyun.com/repository/gradle-plugin/")
        maven("https://maven.aliyun.com/repository/apache-snapshots/")
        maven("https://plugins.gradle.org/m2/")
        maven("https://jitpack.io/")
        mavenLocal()
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        maven("https://maven.aliyun.com/repository/public/")
        maven("https://maven.aliyun.com/repository/central/")
        maven("https://maven.aliyun.com/repository/gradle-plugin/")
        maven("https://maven.aliyun.com/repository/apache-snapshots/")
        maven("https://plugins.gradle.org/m2/")
        maven("https://jitpack.io/")
        mavenLocal()
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

buildscript {
    repositories {
        maven("https://maven.aliyun.com/repository/public/")
        maven("https://maven.aliyun.com/repository/central/")
        maven("https://maven.aliyun.com/repository/gradle-plugin/")
        maven("https://maven.aliyun.com/repository/apache-snapshots/")
        maven("https://plugins.gradle.org/m2/")
        maven("https://jitpack.io/")
        mavenLocal()
        gradlePluginPortal()
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.google.code.gson:gson:+")
    }
}

plugins {
    id("com.android.application") version "8.1.2" apply false
    id("com.android.library") version "8.1.2" apply false
    id("com.google.devtools.ksp") version "2.0.10-1.0.24" apply false
    id("org.jetbrains.kotlin.android") version "2.0.10" apply false
    id("io.github.FlyJingFish.AndroidAop.android-aop") version "2.0.9" apply false
}

include(":app")
应用插件到模块

在app目录下的build.gradle.kts下输入以下代码

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")
    id("io.github.FlyJingFish.AndroidAop.android-aop")
}

dependencies {
    api("androidx.appcompat:appcompat:1.7.0")
    api("io.github.FlyJingFish.AndroidAop:android-aop-core:2.0.9")
    api("io.github.FlyJingFish.AndroidAop:android-aop-annotation:2.0.9")
    ksp("io.github.FlyJingFish.AndroidAop:android-aop-ksp:2.0.9")
}

两步就集成完成了,下面我们开始实战吧

这里通过三个最常见的场景,来演示这个框架的强大功能

更详细的用法,请参考作者Github https://github.com/FlyJingFish/AndroidAOP

使用说明

该框架会在预编译期间自动根据注解生效,不需要自己去初始化SDK或注册对象之类的

直接新建一个AOP Interceptor类,通过注解指定要做什么就能生效

类和方法代理

将项目代码中的特定类和方法,替换为自己的类和方法

package com.android.code.aop

import com.flyjingfish.android_aop_annotation.anno.AndroidAopReplaceClass
import com.flyjingfish.android_aop_annotation.anno.AndroidAopReplaceMethod

@AndroidAopReplaceClass("android.util.Log")
object AndroidLogInterceptor {

    @JvmStatic
    @AndroidAopReplaceMethod("int e(java.lang.String,java.lang.String)")
    fun e(tag: String, msg: String): Int {
        println("AOP AndroidLogInterceptor: $tag $msg")
        return 0
    }
}
方法拦截

可以拦截任意方法,进行额外处理

通过类名+方法名+参数类型+继承关系来匹配,被命中的方法会被拦截

package com.android.code.aop

import com.flyjingfish.android_aop_annotation.ProceedJoinPoint
import com.flyjingfish.android_aop_annotation.anno.AndroidAopMatchClassMethod
import com.flyjingfish.android_aop_annotation.base.MatchClassMethod
import com.flyjingfish.android_aop_annotation.enums.MatchType

@AndroidAopMatchClassMethod(
    targetClassName = "android.app.Activity",
    methodName = ["void onCreate(android.os.Bundle)"],
    type = MatchType.LEAF_EXTENDS
)
class AndroidActivityCreateInterceptor : MatchClassMethod {

    override fun invoke(
        joinPoint: ProceedJoinPoint,
        methodName: String
    ): Any? {
        val target = joinPoint.target!!.javaClass.simpleName
        println("AOP AndroidActivityCreateInterceptor: $target onCreate")
        return joinPoint.proceed()
    }
}
自定义切入点

如果不想写表达式,可以在想要拦截的方法上加一个切入点注解

再定义一个切入点处理器,与注解绑定,来处理拦截工作即可

此外,注解还可以携带一些参数,用于扩展需要

package com.android.code.aop

import com.flyjingfish.android_aop_annotation.anno.AndroidAopPointCut

@AndroidAopPointCut(AndroidContentViewInterceptor::class)
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
annotation class AndroidContentViewPointcut(vararg val args: String = [])
@AndroidContentViewPointcut("HomeActivity")
override fun setContentView(view: View) {
    super.setContentView(view)
}
package com.android.code.aop

import android.graphics.Color
import android.view.View
import com.flyjingfish.android_aop_annotation.ProceedJoinPoint
import com.flyjingfish.android_aop_annotation.base.BasePointCut

class AndroidContentViewInterceptor : BasePointCut<AndroidContentViewPointcut> {

    override fun invoke(
        joinPoint: ProceedJoinPoint,
        annotation: AndroidContentViewPointcut
    ): Any? {
        val target = joinPoint.target!!.javaClass.simpleName
        val pointcut = annotation.args[0]
        val contentView = joinPoint.args!![0] as View
        contentView.setBackgroundColor(Color.YELLOW)
        println("AOP AndroidContentViewInterceptor: before target executed")
        println("AOP AndroidContentViewInterceptor: $target $pointcut setContentView")
        val result = joinPoint.proceed()
        println("AOP AndroidContentViewInterceptor: after target executed")
        return result
    }
}

可以看到,Activity的背景自动变成黄色了,完全不用改动原代码!

而且还能看到,在拦截过程中,我们是可以对原有方法执行流程进行调整的

或者进行预处理,后期处理

尾声

是不是觉得很强大呢,代码也十分简洁

以上特性已经足够满足一般AOP的需求了

如果有更复杂的需求,记得前往作者主页去看一看

标签:aop,编程,maven,https,AOP,Android,com,android
From: https://blog.csdn.net/u013718730/article/details/141314274

相关文章

  • 【花雕学编程】Arduino FOC 之FTC机械臂关节控制
    Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、......
  • 一网打尽,国内外ChatGPT镜像网站集合【2024-08最新】AI编程、AI写作、AI对话、AI翻译、
    一网打尽,我经过一年多搜集的各种AI工具,使用的都是最强最新的大语言模型,都是在各自领域独领风骚的产品。1:【AI站点】AIPlus 推荐指数:⭐️⭐️⭐️⭐️⭐️推荐理由:一个AI综合网站,有多个GPT和绘画站,每个站点都很流畅且可用2:【AI编程】https://zed.dev/推荐指数:⭐️⭐️⭐️⭐️⭐️推荐理......
  • 从开发者视角解析提示词工程:大模型时代的新型编程范式
    1.引言在人工智能飞速发展的今天,大语言模型(LLM)、智能代理(Agent)、检索增强生成(RAG)、以及提示词工程(PromptEngineering)这些词语频繁出现在我们的技术讨论中。今天,我们来聊聊提示词工程,看看它怎么成为开发者手中一种新型的“编程语言”。2.传统软件开发流程回顾说到软件开发,大......
  • Android 存储概览
    存储区​Android一开始就将存储区分为内部存储和外部存储,对应手机自带的存储和可插拔的sd卡(可类比于PC的硬盘和U盘)。内部存储容量有限,Google建议App数据尽量存储于外部存储中。随着硬件技术发展,自带大容量空间的手机开始出现,关于内部存储的描述逐渐偏离现实了,于是从A......
  • Android 10.0 锁屏页面忘记锁屏密码情况下点击5次解锁图标弹出锁屏密码功能实现
    1.前言在10.0的系统ROM定制化开发中,在一些产品中带锁屏密码的功能中,系统默认是滑动解锁,但是客户会设置锁屏密码,在某些时候会忘掉锁屏密码,导致需要进入恢复出厂设置然后才能进入系统桌面,这样就导致系统的保存的资料都丢失了,所以需要要求在锁屏密码页面在忘记解锁密码的情况下......
  • Python是一种广泛使用的编程语言,其主要用途有什么?
    Python是一种广泛使用的编程语言,其主要用途包括但不限于以下几个方面:1.Web开发Python拥有众多Web开发框架,如Django和Flask,这些框架使得开发者能够高效地构建和维护Web应用程序。许多著名的网站,如YouTube、Instagram以及国内的豆瓣等,都是使用Python进行开发的。2.数据科学......
  • DDD的函数式编程实现
    DDD是一种成熟的软件设计方法,旨在确保领域专家和开发人员能够有效合作,创造出高质量的软件。本文介绍咋将FP(函数式编程)应用于DDD的实现,使其既优雅又简洁。C4模型中,软件架构图分为四个层次:“系统上下文”、“容器”、“组件”和“代码”。“组件”是构成容器的基本单位,也是本文描......
  • IPC对象通信方式---共享内存 | 网络通信 -编程
    共享内存共享内存机制其允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取错做读出,从而实现了进程间的通信。是内核预留的内存空间,最......
  • Android的USB网络共享功能
    一、什么是USB网络共享?  USB共享网络是一种基于USB接口的数据传输和资源共享解决方案,例如Android设备作为一个usb网卡连接到其他主机,将Android设备的网络共享给主机使用。在Android系统设置中的“开发者选项”中,可以找到usb的默认配置选择USB共享网络的功能,选择还包括......
  • 人工智能 | 结对编程助手GithubCopilot
    简介GitHubCopilot是一款AI结对程序员,可帮助您更快、更少地编写代码。它从注释和代码中提取上下文,以立即建议单独的行和整个函数。GitHubCopilot由GitHub、OpenAI和Microsoft开发的生成式AI模型提供支持。它可作为VisualStudioCode、VisualStudio、Neovim和Jet......