AspectJ Bytecode Weaving Replaces Boilerplate Network Checks on Android
Android projects accumulate cross-cutting checks—network, permissions, logging—that bloat every screen. Compile-time weaving with AspectJ removes that duplication at the bytecode level, keeping hand-written code focused on business logic while the injected advice handles the guard. The cost is a more complex build and an indirection layer that shows up in decompiled output and stack traces.
A single `@NetworkCheck` annotation, processed by an AspectJ `@Around` advice, intercepts method execution and inspects `ConnectivityManager` before the original body runs. The advice extracts a `Context` from the target object—Activity, View, or Fragment—and either shows a toast and returns null on disconnection or calls `joinPoint.proceed()` to continue. Configuration requires the freefair post-compile-weaving Gradle plugin, an AspectJ runtime dependency, and pointing `AjcWeave` at the platform's `android.jar`.
Decompiling the release APK with jadx confirms the transformation: the original method body is replaced by a synthetic call into a generated static method that wraps the advice. The real business logic gets extracted into a separate `_aroundBody0` method, while the advice method performs the context resolution and network gating before delegating back. This is pure compile-time bytecode manipulation, not runtime reflection.
Beyond network gating, the same pattern applies to permission checks, automatic event tracking, and method-level logging—any cross-cutting concern that would otherwise scatter identical boilerplate across a codebase. The trade-off is longer build times and an extra hop when debugging stack traces.
Bytecode weaving sidesteps the runtime overhead and fragility of reflection-based proxies, but it shifts complexity to the build pipeline—developers must understand what the ajc compiler generates to debug effectively.
The decompiled output reveals that AspectJ does not merely wrap methods; it restructures them into static helpers, which can complicate stack traces and confuse tools that expect original method signatures.
Disabling Gradle configuration cache is a non-trivial concession for larger projects where cache misses already slow down CI, making the build-time cost of AOP more than just the weaving step itself.
The discussion pushes back against AspectJ for Android. The main objection is that a simple singleton with direct method references is more practical than bytecode weaving for tasks like network checks, permissions, or analytics. A separate concern is build time: one report cites AOP adding two minutes to packaging. The original commenter's advice to abandon the approach goes unchallenged.
Before, I was just like you, but now I wouldn't really recommend using this thing. Young man, give it up.
AspectJ, you mean? Or something else?
Yeah, I used to use AspectJ for handling permissions and event tracking too, but I don't anymore. Just making a singleton is more practical — you can directly check method references and immediately know where things are.
I used an AOP framework someone else wrote, and the packaging time was way too heavy. AOP alone took two minutes.