Annotation Processing in Android: From Scratch (Part 1)


3 min read

You must have noticed while implementing dependency injection in Android using Dagger2, how Dagger effortlessly crafts a dependency graph and provides objects at runtime. This marvel is achieved as Dagger2 conjures up a slew of classes during compile time. Ever found yourself pondering, "How does Dagger whip up these classes during compile time?"

Imagine: ๐ŸŽฌ

Imagine you're a chef preparing a grand feast. Instead of manually chopping, dicing, and seasoning every ingredient, you place little notes on each ingredient, instructing your sous-chefs on how to prepare them. These notes? They're annotations. The sous-chefs who follow your instructions? They're the annotation processors.

What's Annotation Processing? ๐Ÿค–

Annotation processing is a powerful feature in Android Studio that allows developers to automate code generation. By placing special notes (annotations) in the code, a tool (the annotation processor) reads those notes and generates additional code based on them. It's a way to reduce repetitive tasks and ensure consistency in the codebase.

Why is it a Game-Changer? ๐ŸŽฎ

  1. Efficiency: Annotations reduce boilerplate code, leading to fewer errors.

  2. Consistency: Generated code follows a standard pattern, ensuring uniformity.

  3. Time-saving: Focus on the core logic while the processor handles mundane tasks.

Under the Hood: How Does It Work? ๐Ÿ› ๏ธ

  • Annotations in Java: Introduced in Java 5, annotations are metadata tags that provide information about the code but don't affect its execution.

  • Annotation Processing Tool (APT): Initially, APT was the tool for processing annotations. However, Java 6 integrated annotation processing capabilities into the Java compiler (javac).

  • The Detailed Process:

    1. Source Code Scanning: During compilation, javac scans for annotations.

    2. Invocation: If annotations are found, javac checks for registered processors for those annotations.

    3. Code Generation: Processors generate additional source files using the Java Filer API.

    4. Recompilation: javac compiles the original and the newly generated source files.

  • Creating Custom Annotation Processors:

    We will be creating our own annotation processor in the upcoming blog posts to understand all these steps in greater detail, but for an overview, we follow the following steps to create our own annotation processor.

      1. Define the Annotation: Use the @interface keyword.

        1. Craft the Processor: Extend the AbstractProcessor class and override the process method.

        2. Register the Processor: Inform javac by creating a javax.annotation.processing.Processor file in the META-INF/services directory.

  • KAPT - Kotlin's Touch: Kotlin introduced KAPT for its annotation processing needs, ensuring compatibility with Kotlin-specific features.

  • Considerations:

    1. No Code Modification: Processors generate new code but can't modify existing code.

    2. Ordering: The sequence in which processors run isn't guaranteed.

    3. Build Performance: Over-reliance can slow down the build process.

Conclusion: ๐ŸŒŒ

Annotation processing is akin to having a team of sous-chefs in your kitchen, diligently following your notes and preparing ingredients. It automates repetitive tasks, ensuring that the main chef (you, the developer) can focus on crafting the perfect dish (your app). It's a blend of automation and manual coding, ensuring efficiency and precision in the development process.

But the journey doesn't end here! In our upcoming blog posts, we'll dive even deeper. We'll roll up our sleeves and create our very own custom Annotation Processor. This hands-on approach will help us grasp the concept in even greater detail, demystifying the magic behind the scenes. So, stay tuned, and let's continue this coding adventure together!

Until then, Bon Appรฉtit and Happy Coding! ๐Ÿฝ๏ธ๐Ÿš€