All Projects → hitanshu-dhawan → AnnotationProcessing

hitanshu-dhawan / AnnotationProcessing

Licence: MIT license
✔️ㅤ[ARTICLE] Writing your own Annotation Processors in Android

Programming Languages

java
68154 projects - #9 most used programming language
kotlin
9241 projects

Projects that are alternatives of or similar to AnnotationProcessing

AnnotationProcessorStarter
Project to set up basics of a Java annotation processor
Stars: ✭ 19 (-59.57%)
Mutual labels:  annotation, annotations, annotation-processor, annotation-processing
MethodScope
Reduce repetitive inheritance works in OOP world using @MethodScope.
Stars: ✭ 33 (-29.79%)
Mutual labels:  annotation, annotation-processor, annotation-processing
simple-annotation-processor
Simple annotation processor example. Inspired by the idea of "How ButterKnife works?"
Stars: ✭ 54 (+14.89%)
Mutual labels:  annotation, annotation-processor, annotation-processing
Placeholderview
This library provides advance views for lists and stacks. Some of the views are build on top of RecyclerView and others are written in their own. Annotations are compiled by annotation processor to generate bind classes. DOCS -->
Stars: ✭ 2,104 (+4376.6%)
Mutual labels:  annotations, annotation-processor, annotation-processing
dagger2-ktx
Kotlin extension bridge library for Dagger2 (proof-of-concept)
Stars: ✭ 41 (-12.77%)
Mutual labels:  annotations, annotation-processor, annotation-processing
aptk
A toolkit project to enable you to build annotation processors more easily
Stars: ✭ 28 (-40.43%)
Mutual labels:  annotation, annotations, annotation-processor
Cvat
Powerful and efficient Computer Vision Annotation Tool (CVAT)
Stars: ✭ 6,557 (+13851.06%)
Mutual labels:  annotation, annotations
Label Studio
Label Studio is a multi-type data labeling and annotation tool with standardized output format
Stars: ✭ 7,264 (+15355.32%)
Mutual labels:  annotation, annotations
Nova
NOVA is a tool for annotating and analyzing behaviours in social interactions. It supports Annotators using Machine Learning already during the coding process. Further it features both, discrete labels and continuous scores and a visuzalization of streams recorded with the SSI Framework.
Stars: ✭ 110 (+134.04%)
Mutual labels:  annotation, annotations
React Image Annotation
An infinitely customizable image annotation library built on React
Stars: ✭ 203 (+331.91%)
Mutual labels:  annotation, annotations
spectree
API spec validator and OpenAPI document generator for Python web frameworks.
Stars: ✭ 190 (+304.26%)
Mutual labels:  annotation, annotations
Router
🍭灵活的组件化路由框架.
Stars: ✭ 1,502 (+3095.74%)
Mutual labels:  annotation, annotations
Kotlin-Annotation-Processor
Annotation Processor Sample in Kotlin
Stars: ✭ 19 (-59.57%)
Mutual labels:  annotation-processor, annotation-processing
Memex
Browser Extension to full-text search your browsing history & bookmarks.
Stars: ✭ 3,344 (+7014.89%)
Mutual labels:  annotation, annotations
annotation-processor-sample
An annotation processor which implements "Builder pattern" for your java classes.
Stars: ✭ 22 (-53.19%)
Mutual labels:  annotation, annotation-processor
Breadcast
Small Broadcast Receiver Library for Android
Stars: ✭ 15 (-68.09%)
Mutual labels:  annotation, annotations
Http Router
🎉 Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)
Stars: ✭ 124 (+163.83%)
Mutual labels:  annotation, annotations
symbok-bundle
Symfony annotations bundle
Stars: ✭ 50 (+6.38%)
Mutual labels:  annotations, annotation-processing
dart sealed
Dart and Flutter sealed class generator and annotations, with match methods and other utilities. There is also super_enum compatible API.
Stars: ✭ 16 (-65.96%)
Mutual labels:  annotation, annotations
annotate
Create 3D labelled bounding boxes in RViz
Stars: ✭ 104 (+121.28%)
Mutual labels:  annotation, annotations

Full article here: https://medium.com/androidiots/writing-your-own-annotation-processors-in-android-1fa0cd96ef11

Android Weekly

What are Annotations ?

An annotation is a form of syntactic metadata that can be added to Java source code.
We can annotate classes, interfaces, methods, variables, parameters etc.
Java annotations can be read from source files. Java annotations can also be embedded in and read from class files generated by the compiler.
Annotations can be retained by Java VM at run-time and read via reflection.

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface BindView {
    int value();
}

Creating an annotation requires two pieces of information: Retention and Target

A RetentionPolicy specifies how long, in terms of the program lifecycle, the annotation should be retained for. For example, annotations may be retained during compile-time or runtime, depending on the retention policy associated with the annotation.

The Target of an annotation specifies which Java ElementTypes an annotation can be applied to.

Why Annotation Processors ?

1. Runtime Compile time

2. No Reflection

3. Generate boilerplate code*

*Annotation processing can only be used to generate new files and not to modify existing ones

How does Annotation Processing work ?

The annotation processing takes place in many rounds. The compiler reads a java source file with the registered annotations and calls their corresponding annotation processors which will generate more java source files with more annotations. These new annotations will again call their corresponding annotation processors which will again generate more java source files. This cycle continues until no new java source file is generated in the cycle.

How to register a Processor ?

A processor must be registered to the compiler so that it can run while the application is being compiled.

Annotation Processors can be registered in two ways.

1.

Create a directory structure like this
<your-annotation-processor-module>/src/main/resources/META-INF/services
Now, in the services directory, we will create a file named javax.annotation.processing.Processor.
This file will list the classes (fully qualified name) that the compiler will call when it compiles the application's source code while annotation processing.

2.

Use Google's AutoService library.
Just annotate your Processor with @AutoService(Processor.class)

Example:

package foo.bar;

import javax.annotation.processing.Processor;

@AutoService(Processor.class)
final class MyProcessor implements Processor {
  // …
}

How to create a Processor ?

To create our custom Annotation Processor we need to make a class that extends AbstractProcessor which defines the base methods for the processing.
We have to override four methods to provide our implementations for the processing.

public class Processor extends AbstractProcessor {

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        // initialize helper/utility classes...
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
        // do processing...
        return true;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return new HashSet<String>() {{
            add(BindView.class.getCanonicalName());
            add(OnClick.class.getCanonicalName());
        }};
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}

init() gives you Helper/Utility classes like Filer (to generate files), Messager (for logging errors, warnings etc.), Elements (utility methods for operating on program elements), Types (utility methods for operating on types) etc.
You can get these classes with processingEnvironment.

process() is the method where all the processing happens.
It gives you annotations that need to be processed and roundEnvironment provides the information about the round and has some utility methods for querying elements.
e.g. processingOver(),getRootElements(),getElementsAnnotatedWith() etc.

getSupportedAnnotationTypes() returns the names of the annotation types supported by this processor.

getSupportedSourceVersion() returns the latest source version supported by this processor.

Note : You can also use @SupportedAnnotationTypes and @SupportedSourceVersion instead of getSupportedAnnotationTypes() and getSupportedSourceVersion() respectively.

Demo #1 : Singleton

  1. Singleton.java
  2. Processor.java

Demo #2 : KSingleton

  1. KSingleton.kt
  2. Processor.kt

Important Classes/Objects

ProcessingEnvironment : An annotation processing tool framework will provide an annotation processor with an object implementing this interface so the processor can use facilities provided by the framework to write new files, report error messages, and find other utilities.

Elements : Utility methods for operating on program elements. Can be accessed by ProcessingEnvironment.getElementUtils().

Types : Utility methods for operating on types. Can be accessed by ProcessingEnvironment.getTypeUtils().

Messager : A Messager provides the way for an annotation processor to report error messages, warnings, and other notices. Can be accessed by ProcessingEnvironment.getMessager().

Filer : This interface supports the creation of new files by an annotation processor. Can be accessed by ProcessingEnvironment.getFiler().


RoundEnvironment : An annotation processing tool framework will provide an annotation processor with an object implementing this interface so that the processor can query for information about a round of annotation processing. We can get our desired elements with RoundEnvironment.getRootElements() and RoundEnvironment.getElementsAnnotatedWith() methods.


ElementFilter : Filters for selecting just the elements of interest from a collection of elements. Contains methods like ElementFilter.constructorsIn(), ElementFilter.methodsIn(), ElementFilter.fieldsIn() etc.

How to generate .java files ?

We can use Square's JavaPoet library for generating .java files.
JavaPoet makes it really simple to define a class structure and write it while processing. It creates classes that are very close to a handwritten code.

Example

This HelloWorld class

package com.example.helloworld;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, JavaPoet!");
  }
}

can be generated by this piece of code

MethodSpec main = MethodSpec.methodBuilder("main")
    .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
    .returns(void.class)
    .addParameter(String[].class, "args")
    .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(main)
    .build();

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build();

javaFile.writeTo(System.out);

Note : There's also another Square library KotlinPoet for generating .kt files.

Demo #3 : ButterKnife

Annotations

  1. BindView.java
  2. OnClick.java

Processor

  1. Processor.java

Library

  1. ButterKnife.java

Example

This ButterKnife library will generate separate classes (with suffix Binder) for each of the Activity where we used the annotations @BindView or @OnClick.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private int numberOfTimesTextViewClicked = 0;

    @BindView(R.id.text_view)
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);
    }

    @OnClick(R.id.text_view)
    void onTextViewClicked(View view) {
        textView.setText(String.valueOf(++numberOfTimesTextViewClicked));
    }
}

MainActivityBinder.java

public class MainActivityBinder {
    public MainActivityBinder(MainActivity activity) {
        bindViews(activity);
        bindOnClicks(activity);
    }

    private void bindViews(MainActivity activity) {
        activity.textView = (TextView) activity.findViewById(2131165314);
    }

    private void bindOnClicks(final MainActivity activity) {
        activity.findViewById(2131165314).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                activity.onTextViewClicked(view);
            }
        });
    }
}

References

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].