May 16, 2019
Developer community have tons of information to process after Google I/O’19 sessions. The session made it clear that it is going to be Kotlin first for Android. It covered the progress made in Android support for Kotlin and Kotlin-centered universe like Kotlin samples and reference docs, annotations, framework APIs, IDE support for low-level byte code optimizations in the D8/R8 compiler.
But besides all the big fancy things that got mentioned in the keynote, we are going to check out what’s new in android architecture components.
1. Data Binding
Data Binding is declarative UI inside XML. It tries to bridge the gap between your code and your XML
Data Binding has been real pain for developers. The binding classes are generated on compilation so for every small change we need to compile whole source.
Compilation speed is significantly improved. Now it is 20% faster while it runs the annotation processor. They have added support for distributed Gradle cache so that you can benefit from your peers compiling the projects.
In Android Studio 3.5, we have an incremental annotation processor for data binding. It is experimental yet so you need to turn it on before using it. Put following line of code into your Gradle file to turn it on:
android.databinding.incremental = true
Live Class Generation
Before this, if you create new XML bindings or add new views and widgets to your declarative XML then you would have to recompile the source code by building the projects again. Let’s say you have a view in your declarative XML and then you assign an id to it then you have to build the project again in order to get data binding generated for it! How we can avoid this?
Live Class Generation comes to the rescue. What does this mean is when you assign an id to a view or add new views or widgets to your declarative layout for which binding is already generated, you don’t need to rebuild the whole thing. The corresponding binding class will be generated with the latest changes for you. How amazing is that! No need to wait for build process to complete!
Lets say you want to remove id of some view. As soon as you do that, corresponding bindings will be invalidated immediately! This works for binding variables also. You declare a new variable in your XML layout and it is available into your binding object in no time! Cool, right?
Back in old days, whenever we refactor some variable or method that is bound with some of your UI in XML using data binding, studio doesn’t notify that this particular variable or method is used somewhere in you declarative XML layouts and most of the times we end up with project not being compiled because it cannot find that variable or method as that is refactored! But you have had enough, no more pain now!
Now if you want to refactor that method or variable and as soon as you do that android studio updates related bindings automatically for us!
Also you can do the same thing from XML. You refactor something from XML and studio will automatically update your code.
Better Error Messages
Data Binding error messages has been real mess since Data Binding was introduced for the first time. If something is broken for binding, say it cannot find particular view or variable, it shows thousands of errors in your log cat. Sometimes this stack-traces are so huge that you cannot even see the actual error that broke the project and build process. I has been happened to me for many times and know this: You’ll never find out what the actual problem was even after wasting hours and hours!
But you have suffered enough! They have fixed this problem. Also, they have added a separate section that is specific to Data Binding errors! I’m going crazy!!
2. Accessing Views
These are the options we have when it comes to access a view in Android. Using Following evolution chart from the related IO talk, they evaluated them in terms of elegance, compile time safety and build speed impact!
We’re looking for the last one that satisfies all the terms. What it could be? Here comes View Binding.
The new View Binding feature is going to be available in Android Studio 3.6. It is totally compile time safe and it doesn’t have any impact on your build speed.
Below snippet represents what we are used to do which is using one of the methods from above chart to access our views.
We don’t need to do those things, we can use generated binding class after it is inflated and then set the content view. Doing this, we are going to have all the views with IDs as public final fields in that binding object.
If the id with correct type doesn’t exist then the code will not compile. This is how we get 100% compile time safety. As it is also usable from Java.
If your code compiles then that means your views do exist in the right layout.
All this binding classes are generated by the Android Studio Gradle plug-in. So if you change a layout file then it the only file that gets invalidated.
It has full Android Studio integration and it is fully compatible with Data Binding.
If you’re using Data Binding just to access your views then you can turn it off and turn on View Binding and your code will compile as it is.
3. ViewModel + SavedStated
Alright, here’s the big picture:
- You have your stuff.
- you put your stuff into
- configuration change happens.
- You go back to your
SavedStateand grab your stuff out of it.
This makes us think that both
SavedState are similar but actually that’s not true.
SavedState travels to the system server which is a separate process so this is “Travel across process boundaries”.
In contrast to SavedState,
ViewModel always lives in process memory. It never leaves it.
Configuration changes doesn’t affect it at all because memory is continuous for this process and your
ViewModel is still there. If the process is restarted for some reason, then you have NOTHING.
So now we know that
SavedState are different things. But They can work together. Here is how we can use it.
SavedStateHandle instance in
ViewModel constructor. This instance will allow you to access
SavedState right into your
SavedStateHandle is a map like object with very straightforward api.
They have also provided convenience api for
SavedState is mutable data so it is
Kotlin Friendly Code
They kind of paid their debts in other fields of
LifeCycle and made some of the code much Kotlin friendly then it was earlier.
Introducing lambda block support for
Before (Java friendly code):
Now (Kotlin friendly code):
No need to use static methods on transformations. Instead now we have extension functions:
No need to use
lateinit var for Initialization.
Now we have property delegation:
WorkManager is a background processing library for work that doesn’t have to be executed right away. It is persistent so it can go across app restarts and device restarts. It is also constraints based so you can have work that only triggers when some conditions are met like network access.
The hard thing about WorkManager is that it needs to be initialized when your app starts up. This new on-demand initialization will allow you to start WorkManager only when you need it. That’s quite good.
It is currently available in WorkManager 2.1 alpha. You can implement
Configuration.Provider in your application class . It has a method that needs to be overridden which returns a
WorkManager configuration object.
Currently in WorkManager 2.0, you can get WorkManager instance by calling
WorkManager.getInstance() with no arguments. In WorkManager 2.1, If you provide
context as argument then it indicates WorkManager that if it is not Initialized then it can go to the application object and get the configuration.
Google play Services Integration
- Better performance on pre-marshmallow devices.
- Totally optional. Checks if you’re using play services and uses it if you do. Just needs a Gradle dependency to enable it.
WorkManager released, it had some problems working with
Roboletrics but it works perfectly fine with the release of WorkManager 2.1 alpha.
Worker Unit Testing (alpha)
Workers can be created using these classes
TestListenableWorkerBuilder and you can use them by calling
Foreground Services Support
Later this year, support for foreground services will be added to the
WorkManager apis. You can use it to do your work in foreground. Both
JobScheduler give you a 10 minutes of slice to do your task. If your task go longer than that then you can make use of a foreground service for that.
From Room 2.1,
Dao can have suspending methods and Room will generate correct code including using a background dispatcher. You can have suspending methods which do transaction also.
Room also includes a extension function that will allow us to start a transaction. It creates a special
CoroutineContext that we can use to perform multiple database operations.
Full Text Search
Full Text Search is an extension in SQLite to be able to create tables to efficiently search for data.
Let’s say we are trying to create a search functionality for a music app like we want to search for a given phrase. In Room 2.0, we would have to write a
Dao method kind of like this:
It doesn’t look great, there is a huge
WHERE clause. But in Room 2.1, if you want an entity to be able to be backed by an
fts table, just simply use the
fts annotation. It simplifies your query to this as you can start using
Database Views is another way to simplify your database operation.
Database Views are kind of like tables where everywhere you reference a table, you can reference a view but you cannot insert data into views. They are kind of like queries with a given name.
Let’s say we want to display a list of albums. In Room 2.1, instead of having a BigQuery, you can annotate your data class(your entity for Room 2.0) with
@DatabaseView. So instead of making a table, we’ll create a view out of it. Then we have to put our BigQuery in the annotation to specify how we get our data for the view.
The import thing is now we can use this view as if it was another table.
Expanded Rx Support
In Room 2.1, now you can have insert, update and delete method that return
Single. You also use Rx as return type for Query tag that performs write statements such as insert update or delete operation.
- Incremental Annotation Processor
- Relationship Improvements
- Migration Improvements
- Coroutines Channels & Flow
- Built in network support with error handling
- Headers & Footers
- Better RxJava & Coroutines Integration
- ViewModel scoped to the navigation graph.
- Navigate by URI
- Dialog Destinations
- Better support for dynamic features
That’s it. Thank you guys for reading. If you liked what you read, don’t forget to clap 😁. Happy coding folks!