Why Are Kotlin Synthetics Deprecated and What Are the Alternatives?
Comparing which one to use: data binding vs. view binding vs. Kotlin Synthetics vs. findViewById

Recently Android has announced that with Kotlin 1.4.20, their Android Kotlin Extensions Gradle plugin will be deprecated and will no longer be shipped in the future Kotlin releases.
Android Kotlin Extensions plugin brought with it two very cool features :
- Synthetics let you replace calls to
findViewById
withkotlinx.android.synthetic
bindings. - Parcelize allows you to remove boilerplate and easily create Parcelables through the
@Parcelize
annotation.
And with the deprecation of this plugin, we will no longer be able to use these features. Don’t worry about Parcelize, as it will be now shipped as a standalone plugin: kotlin-parcelize. But this is definitely going to be the end for Kotlin Synthetics.
Now Android developers all across the globe, have, with a very heavy heart, to say goodbye to Kotlin Synthetics. But first, let's understand why Kotlin Synthetics was introduced in the first place, why it’s deprecated now, and what the options are for us apart from it.
“Necessity is the mother of invention”
History — findViewById
Earlier, to get the IDs of views, we were dependent upon findViewById
.
This method looks very simple, but there were a lot of issues with this that developers were facing.
This function works by traversing the view hierarchy to find a widget with the ID you specified. It returns the view as soon as it is found or it returns null
if it is not present. Let's discuss some of the issues with this approach:
- By looking at how it works above, we can say that this method is costly. Developers would use it exhaustively at runtime, especially in the earlier implementations of list view’s adapter, and it made their code perform poorly.
- If your view is not present in the layout, you will get
NullPointerException
at the runtime, i.e., not null safe. - Prior to Android API 26, it returned the view (parent class) which you have to manually type cast, and a wrong cast would lead to
ClassCastException
, i.e., not type safe. - A lot of boilerplate code. You have to write the same method for all your views, type cast them, and then assign them to a variable.
Then libraries like Butter Knife came along to make this approach simpler. Butter Knife improves the issue of boilerplate code partially but still has not solved issues with type safety and null safety. Moreover, it used annotation processing which did slow down the build time a bit. (Note: Butter Knife is now deprecated.)
Kotlin Synthetics to the rescue
With the Android Kotlin Extensions Gradle plugin released in 2017 came Kotlin Synthetics. For every layout file, Kotlin Synthetics creates an autogenerated class containing your view— as simple as that.
You just have to import this plugin in your Gradle file, and you are all set to directly refer to the view reference variables.
It calls findViewById
internally only once and then caches it.
This was so convenient and such fun to use, so why is it being deprecated
Let's analyze it.
Pros
- No boilerplate code — Just configure it once in your Gradle file and you are all set to go. Kotlin Synthetics will automatically generate a class ready for you to use.
- Type safety — All views are picked from your layout file with the type known to it.
Cons
- Partial null safety — It is generally null safe as all your views must be present in the layout file for it to generate. But what if you have multiple layout files based on configurations where some views are present in some layout files and missing in some? Here you have to then manually check for null.
- Pollutes the namespace — You can have the same view ID in different layouts, and you can accidentally import a view of some other layout, which will later at runtime throw
NullPointerException
. - Kotlin only — Kotlin Synthetics can only be used with Kotlin. They are not supported with Java. There are still projects that are written in Java and may not be fully migrated to Kotlin yet, and hence Kotlin Synthetics may not be a consistent way of getting the ViewIds in your project.
Because of these issues, Kotlin Synthetics is now being deprecated.
But what to use instead of it? Should we head back to the previous findViewById
approach, or are there are some other recommended ways to achieve the same?
Let's find out about some recommended approaches.
Data Binding
As stated in the documentation, “the Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.”
To get started, configure your app to use data binding and enable the dataBinding
build option in your build.gradle
file in the app module.
android {
...
buildFeatures {
dataBinding true
}
}
To enable data binding in a layout, you have to manually add the <layout>
tag in your layout.
Android Studio will automatically generate classes for your layouts with the Binding
suffix. For example, if your layout file name is activity_main.xml
, then Android will generate a class called ActivityMainBinding.
Data binding is very powerful with its support for the following:
- Binding expressions with layouts
- Work with observable data objects
- Binding adapters
- Two-way bindings
Pros
- Null safety — It is null safe. Even if we have multiple layouts based on configurations and few views are present/missing from other configuration layouts, that view would be annotated as
@ Nullable
. - Type safety — As all views are picked from your layout file with the type known to it.
- Supports both Kotlin and Java
Cons
- Boilerplate code — Each layout file requires you to manually add the
<layout>
tag in order for it to support data binding. - Increased build time — Data binding can increase the build time as it has to generate class files with view and, moreover, with their getter, setter, and evaluating expressions.
View Binding
Simply, View binding is a very much simpler version/a subset of data binding.
The difference between the two is that view binding is only for view references and not for binding UI with data sources.
To get started, configure your app to use data binding and enable the viewBinding
build option in your build.gradle
file in the app module.
android {
...
buildFeatures {
viewBinding true
}
}
For view binding, you do not have to declare anything in your layout file. By default, all layout files will have a generated class file with the Binding
suffix ready for you to use.
Advantages of View Binding
- Null safety — Same as data binding
- Type safety — Same as data binding
- No boilerplate code — Unlike in data binding, all layouts are by default eligible for the generation of binding class without any tag.
- No impact on build time — Unlike in data binding, there is no negative impact on the build time.
- Supports both Kotlin and Java.
Conclusion
View binding and data binding should be the recommended approach.
For simpler user cases, use view binding instead of Kotlin Synthetics, and if you are living under a rock and are still using findViewById
, then it is high time to migrate.
If you want to start with data binding and be amazed by its benefits, then it is time to migrate to data binding.
Alternatively, you can use both view binding and data binding together.
All your layout files with the <layout>
tag will work with data binding, while other layouts will work with view binding.
Parting Words
Feel free to comment and let me know your suggestions. Do suggest topics that you would like me to cover in my coming articles.
That’s all! Thank you!