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š.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Annotation Processing: Supercharge Your Development
25 mins
- Getting Started
- Starting Your First Annotation
- Exploring Annotation Anatomy
- Adding Another Annotation
- Introducing Annotation Processing
- Creating Your First Annotation Processor
- Adding Basic Processor Structure
- Registering Your Processor
- Extracting Annotation Metadata
- Coding Model Classes
- Processing the Annotations
- Generating Source Code
- Specifying the Output Folder
- Using KotlinPoet
- Adding the Processor to Your App
- Where to Go From Here?
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
- Makes the annotations you’ve created at the start available for use in your app.
- 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:
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.
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!