Self-hosted service
FlyJingFish/AndroidAOP avatar
FlyJingFish/AndroidAOP

AndroidAOP: static AOP weaving for Android without AspectJ

🔥🔥🔥A framework that helps Android App transform into an AOP architecture. (帮助 Android App 改造成AOP架构的框架,一个注解就可以请求权限、切换线程、禁止多点、监测所有点击事件、监测生命周期等等)

858 stars70 forksKotlinApache-2.0

At a glance

What is it?
AndroidAOP is an Apache-2.0 Kotlin framework that lets an Android app adopt aspect oriented programming through a Gradle plugin, with built in aspects for permissions, thread switching, duplicate click blocking, click monitoring and lifecycle tracking. It suits teams that want cross cutting behaviour in one place, and it demands a modern Gradle setup and a willingness to let a build step rewrite bytecode.
Who is it for?
AndroidAOP fits an Android team whose code has grown the usual tangle of permission checks, thread hopping and duplicate click guards scattered across activity and fragment classes, and it gives those concerns a single place to live without adopting AspectJ. It does not fit a project that must stay on an old Gradle, one that cannot accept bytecode rewriting at build time, or one that wants runtime weaving with no build cost.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 133 days ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Cross cutting Android concerns are the target, not general purpose AOP

The pitch in the README is a framework that helps an Android app transform into an AOP architecture, where with just one annotation you can request permissions, switch threads, prohibit multiple clicks, monitor all click events at once and monitor the life cycle.

Read that list closely and you can see the actual scope. These are not generic logging or transaction aspects. They are the chores that every Android codebase accumulates in every screen: ask for a permission before doing the thing, move work off the main thread, stop a double tap firing two requests, log where the user tapped, and track what happened to the component. The framework is aimed at developers who are tired of that boilerplate spread across activities, fragments and view models.

The audience is therefore mid sized Android teams with existing Kotlin or Java code that they cannot rewrite, but can decorate. Aspect oriented programming is attractive here because you can add behaviour around existing methods without restructuring the class that owns them.

There is also a tooling angle. The README points to a plug-in assistant for generating the code for a custom aspect, and to an online documentation site with an English and a Simplified Chinese version, which suggests a project built for a wide developer audience rather than an internal tool.

Static weaving at build time, without the AspectJ runtime

The implementation choice that matters most is stated twice in the README. The library supports the generation of all cutting information json and html files, and it is pure static weaving into AOP code, and it is not implemented based on AspectJ, with the amount of woven code described as very small and the intrusion as extremely low.

That is a design decision with real consequences. Static weaving happens during the build: the plugin modifies your bytecode so the aspect advice is already inside the method when it runs. There is no runtime agent, no weaver hooked into the class loader, and no AspectJ dependency to manage in a debug build.

Projects that do adopt AspectJ typically take on an AspectJ dependency and weaver tooling in the build, and woven frames that are not in your source can make stack traces harder to read.

The trade-off sits on the other side of the ledger. Because weaving happens at build time, the plugin participates in your Gradle build, and the README documents configuration keys for how the packaging method is set during development, plus a component based development mode, both of which exist to keep that build from slowing you down.

Adding the plugin to the root build.gradle is the only required step

The setup is short. The README describes introducing the plug-in as the required first step, with two supported methods, and points at the root build.gradle in the project root directory for the dependency.

The plugins DSL form applies the plugin automatically to all modules when apply is set to true.

gradle
plugins {
    id "io.github.flyjingfish.androidaop" version "2.7.6" apply true
}

The legacy form declares the plugin on the buildscript classpath instead, which is what a project still using the older plugin application style needs.

gradle
classpath 'io.github.flyjingfish:androidaop-plugin:2.7.6'

Two details in those snippets matter. The version string tracks the published release, currently 2.7.6, and the artifact identifier differs between the two methods, with io.github.flyjingfish.androidaop for the DSL and io.github.flyjingfish:androidaop-plugin for the classpath. Mixing them up produces a resolution error rather than a subtle fault.

The rest of the configuration lives in the online documentation. The README lists an optional configuration item for the AndroidAOPConfig block in the app build.gradle, and an optional step for setting the packaging method during development.

Built in aspects cover the common chores, custom aspects cover the rest

The library ships with commonly used aspect annotations so you do not have to write them, and it also lets you write your own aspects with what the README calls simple and easy syntax.

The built in set covers the behaviours named in the summary: requesting permissions, switching threads, prohibiting multiple clicks, monitoring click events and monitoring the life cycle. For an Android team, that is most of the cross cutting code that tends to be copied from project to project.

Writing your own aspect is the other half. The important detail is that the framework does not require AspectJ for this, which means the pointcut syntax and the weaving behaviour are the project's own rather than inherited from a large general purpose library. The cost of that choice is that the pointcut syntax you already know may not apply, and the documentation has to be read carefully before you write anything non trivial.

The repository layout supports this reading. There are separate modules for the annotation definitions, the annotation processing step, the core runtime, extra utilities and the Gradle plugin itself, plus test modules including a test app, a test Java library and a test library, and a dynamicfeature directory that suggests component based development is exercised in the repository rather than only described.

Weaving into third-party code, lambdas and suspend functions

Three of the listed features decide how useful the framework is for a real codebase, and they are worth separating because each covers a case that naive weaving usually misses.

The first is cutting into third-party libraries. If your problem is a click handler inside a vendor SDK, or a lifecycle callback in a library you do not control, then advice on your own classes is not enough. The README lists support for cutting into third-party libraries as a feature of the framework.

The second is the case where the cutting method is a Lambda expression. Lambda shaped call sites are awkward for a pointcut matcher, and support here means the aspect can target the function object rather than only named methods.

The third is the coroutine function modified by suspend. With suspend functions, the interesting boundary is the suspension point, not the call site, and the README states that the framework supports cutting a suspend function as the cutting method.

Taken together, these three are the difference between a framework that works in a demo and one that works in a Kotlin codebase that already uses lambdas and coroutines heavily. They also explain why the project needs its own annotation processing module rather than only a bytecode transform.

Debug mode and the json and html cut reports address build time cost

Every static weaving framework has the same objection: the build gets slower and the debugging story gets worse. The README addresses both, in its own words, as supporting multiple rapid development modes that make packaging speed almost unchanged, and as supporting component based development with a link to the debugMode configuration.

The mechanism behind that is not spelled out in the README beyond the configuration links, so treat the claim as a design intention to verify rather than a measured guarantee. What is clear is that the framework treats development speed as a first class requirement and offers a switch for it.

The other half of the story is visibility. The framework supports generating all cutting information as json and html files, which the README says is convenient for viewing all cutting locations. For a mechanism that rewrites bytecode, that report is the audit trail: you can see which methods in which classes were actually woven, which is how you catch an over broad pointcut before it ships.

The report is also the fastest way to answer the question a reviewer will ask, which is why this code was affected by an aspect in the first place.

Gradle 7.6, minSdk 21 and a plugin that has tracked Gradle releases

Two hard version constraints are stated in the README. The minimum Gradle version is 7.6, and the minimum SDK version is minSdkVersion 21.

These are real adoption gates rather than fine print. A project still on an older Gradle cannot apply the plugin at all, and since the plugin is the required first step of the setup, that ends the evaluation immediately.

The release history shows the project keeping pace with the build system rather than standing still. Version 2.7.6 was published on 2026-06-15 with a bug fix, 2.7.5 on 2026-04-29 adapted the plugin to Gradle 9, and 2.7.4 on 2025-12-09 fixed bugs and added an includeKotlin configuration. That last item is worth noting, because it implies that Kotlin weaving is something you can control rather than an all or nothing behaviour.

The last push to the repository was on 2026-06-15, which matches the 2.7.6 release date, and the project is Apache-2.0 licensed with the LICENSE file in the repository root. For a build time plugin, the upgrade cost is the real cost: because weaving runs inside your Gradle build, a plugin upgrade can change which methods are advised, and the json and html cut reports are how you diff that between versions.

Editorial conclusion

AndroidAOP fits an Android team whose code has grown the usual tangle of permission checks, thread hopping and duplicate click guards scattered across activity and fragment classes, and it gives those concerns a single place to live without adopting AspectJ. It does not fit a project that must stay on an old Gradle, one that cannot accept bytecode rewriting at build time, or one that wants runtime weaving with no build cost. Before you wire it in, check that your Gradle version is 7.6 or later and your minSdkVersion is 21 or above, since the README states both as hard minimums, confirm the plugin coordinates match the release you intend to use, and read the notes for the 2.7.5 release, which adapted the plugin to Gradle 9, because the last push to the repository was on 2026-06-15 and newer Gradle compatibility is where breakage appears first.

Frequently asked questions

How do I add AndroidAOP to an Android project?

Add the plugin in the root build.gradle, using the plugins DSL with id "io.github.flyjingfish.androidaop" version "2.7.6" apply true, or the legacy buildscript classpath form with io.github.flyjingfish:androidaop-plugin. This step is required before anything else.

Does AndroidAOP use AspectJ?

No. The README states that the library is not implemented based on AspectJ, that it is pure static weaving into AOP code, and that the amount of woven code is very small with extremely low intrusion.

What are the version requirements for AndroidAOP?

The README states a minimum Gradle version of 7.6 and a minimum SDK version where minSdkVersion is 21 or higher. Version 2.7.5 adapted the plugin to Gradle 9.

Can AndroidAOP weave into third-party libraries and suspend functions?

The listed features include cutting into third-party libraries, cutting where the cutting method is a Lambda expression, and cutting a coroutine function modified by suspend.

How can I see which code AndroidAOP has modified?

The framework supports generating all cutting information as json and html files, which the README describes as convenient for viewing all cutting locations. There is also an optional configuration item for the AndroidAOPConfig block in the app build.gradle.

Official sources

  1. FlyJingFish/AndroidAOP on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/flyjingfish-androidaop.svg)](https://hysenlabs.com/projects/flyjingfish-androidaop)

Was this useful?