Annotation Processing: Supercharge Your Development

Annotation processing is a powerful tool for generating code for Android apps. In this tutorial, you’ll create one that generates RecyclerView adapters. By Gordan Glavaš.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Adding the Processor to Your App

Wiring an annotation processor to your app is dead simple. Open app/build.gradle and add these two dependencies to it:

implementation project(':autoadapter-annotations') // 1
kapt project(':autoadapter-processor') // 2
  1. Makes the annotations you’ve created at the start available for use in your app.
  2. Hooks the annotation processor into your compilation process.

You also need to configure the app so that it knows how to use generated files as source sets. In app/build.gradle, add this block right after buildTypes inside the android block:

  sourceSets {
    main {
      java {
        srcDir "${buildDir.absolutePath}/generated/source/kaptKotlin/"
      }
    }
  }

Make sure to sync your project with Gradle files before you proceed!

For the annotation processor to run, at least one element in the codebase must be annotated with one of its supported annotations. Open Person.kt and annotate the class with AdapterModel:

@AdapterModel(R.layout.layout_person)
data class Person

R.layout.layout_person is the layout file that the ViewHolder will inflate.

Next, annotate the model class’s fields with ViewHolderBinding:

  @ViewHolderBinding(R.id.name) val name: String,
  @ViewHolderBinding(R.id.address) val address: String

You’re good to go! Build and run. When it’s done, search for PersonAdapter.kt and open it:

Searching for PersonAdapter

It should look something like this:

package com.raywenderlich.android.autoadapter

import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView.Adapter
import kotlin.Int
import kotlin.collections.List

class PersonAdapter(
    private val items: List<Person>
) : Adapter<PersonAdapter.ViewHolder>() {
  override fun getItemCount(): Int = items.size

  override fun onCreateViewHolder(
      parent: ViewGroup, 
      viewType: Int
  ): PersonAdapter.ViewHolder {
    val view = android.view.LayoutInflater.from(parent.context)
        .inflate(2131361822, parent, false)
    return ViewHolder(view)
  }

  override fun onBindViewHolder(
      viewHolder: PersonAdapter.ViewHolder,
      position: Int
  ) {
    viewHolder.bind(items[position])
  }

  class ViewHolder(
      itemView: View
  ) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {
    fun bind(item: Person) {
      itemView.findViewById<TextView>(2131165330).text = item.name
      itemView.findViewById<TextView>(2131165248).text = item.address
    }
  }
}

The actual numbers for the view and layout IDs will likely differ, but everything else should be the same. Consider how powerful this is: Whenever you add a new model file, you can have a fully functional adapter just by adding a few annotations to the file. This takes a fraction of the time needed to write the class yourself.

It gets even better! If you change anything in the model, the adapter will follow suit. If you remove the model class, the adapter goes as well.

Time to make use of the newly generated adapter file. Open MainActivity.kt and replace the TODO in onCreate with the following:

adapter = PersonAdapter(listOf(
    Person("Big Bird", "123 Seasame Street"),
    Person("Kermit the Frog", "6801 Hollywood Blvd.")
))

Build and run. What you’ll see is a plain old RecyclerView showing a few bits of data. However, it’s powered by your newly generated adapter.

The populated RecyclerView

Where to Go From Here?

You can download the final version of this project using the Download Materials button at the top or bottom of this tutorial.

Congratulations on making it all the through! You’ve learned a lot about annotations and annotation processing, and you created a handy processor that will generate adapter classes for you.

You can read more about the @Target and @Retention annotations in the official Java docs.

Be sure to read more about KotlinPoet to familiarize yourself with all the awesome things it can do.

If you have any questions or comments, please join the forum discussion below!