Android Annotation Processing Review

Janishar Ali
MindOrks
Published in
3 min readJul 9, 2018

The old has risen from the grave and now became the new kid in the town with a cool label.

android-annotaion-processing-review-cover

If you have ever encountered @Singleton or @BindView and thought it works mysteriously and sometimes seems like magic, then you are right at my place. Take for example Dagger2, it provides the instance of a class where we need to simply define the recipe for its construction through @Provides. It is this annotation processing that hides all the complexities from you. Another interesting example is ButterKnife, the savior of the findViewById and ugly casts. It’s magic also arise from annotation processing.

Now, an interesting fact: All the magic becomes obvious when you learn the trick. So, I will help you with the insights to unfold the mysteries of this super cool tool.

It is very important to understand the underlying details of annotation processing because most of the major libraries that constitute the major part of modern Android development, use annotation processing.

I explored annotation processing when I was converting my library PlaceHolderView from reflection to code generation. I will share my experiences during this journey in the tutorials to follow.

Java supports annotation processing from the release of Java 5 but its full potential has been realized in the recent years. Annotation processing in simple words is that it generates files during compilation.

We very well know that Java reflection is a slow process as it requires an extensive search to find a method or variable declaration for a class. The annotation processing removes the need of reflection by generating code that replaces the search with an actual method call.

This is an advanced topic for Android development, but I believe most of you are an advanced developer ;-)

To make this learning process playful and informative, I have written a 4 part tutorial that covers the subject with a complete example: The example creates a library very similar to ButterKnife that maps the View’s id with its object and OnClickListerner to a View of an Activity.

public class MainActivity extends AppCompatActivity {

@BindView(R.id.tv_content)
TextView tvContent;

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

@OnClick(R.id.bt_1)
void bt1Click(View v) {
tvContent.setText("Button 1 Clicked");
}

@OnClick(R.id.bt_2)
void bt2Click(View v) {
tvContent.setText("Button 2 Clicked");
}
}

You will learn to define your annotations: @OnClick and @BindView

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

You will learn to create your own annotation processor that will generate code similar to this using JavaPoet.

package com.mindorks.annotation.processing.example;

import android.view.View;
import android.widget.TextView;
import com.mindorks.lib.annotations.Keep;

@Keep
public class MainActivity$Binding {
public MainActivity$Binding(MainActivity activity) {
bindViews(activity);
bindOnClicks(activity);
}

private void bindViews(MainActivity activity) {
activity.tvContent = (TextView)activity.findViewById(SOME_ID);
}

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

Here are the links to the tutorials:

  1. Part 1: A practical approach
  2. Part 2: The project structure
  3. Part 3: Generate Java source code
  4. Part 4: Use the generated code

Here is the link to the GitHub repository for the example project:

Learning is a journey, let’s learn together!

Thanks for reading this article. Be sure to share this article if you found it helpful. It would let others get this article and spread the knowledge. Also, put a clap it’s good for the health ;)

Let’s become friends on Twitter, Linkedin, Github, and Facebook.

--

--

Janishar Ali
MindOrks

Coder 🐱‍💻 Founder 🧑‍🚀 Teacher 👨‍🎨 Learner 📚 https://janisharali.com