Skip to main content

Posts

Showing posts from August, 2019

How to produce the SavedStateHandle in your ViewModel using AssistedInject

One of my previous article Dagger Multibinding Saved My Time "claimed" to have found the right practice for providing ViewModels without producing a ViewModel Factory for each ViewModel. Apparently, I was wrong.  There are 2 main problems with that approach:

1 - I might forget to add a ViewModel in the Map graph.
2 - With the new SavedStateHandle which stays uniqely in each ViewModel I can't use a generic ViewModel Factory.  (you can check the implementation in the article provided above).

So,  what does AssistedInject do to help solve this case?

Check this example below:


Dagger doesn't know how to create  a SavedStateHandle. And since the SavedStateHandle cannot be used as a Singleton, we want a different state for each of our fragments. In order to achieve this, let's allow the AssistedInject library create a unique Factory for us. It might require a little more work on configurations, but after the set up, it's just kindergarten game for you.

Instead of  …

Solving Room "cannot find setter for field" error in build time

Room persistence library is one of the easiest one to set up. However, when using data classes for your Room entities, you might face some small problem, which on the first look doesn't really make any sense.

Let's try to compile this class:

The problem:


But I already have a data class entity that has only vals.  Why doesn't this class compile?
The problem here is the class UserGrade that room has no idea how give a value to it. Furthermore, that's a non nullable type. Even though I'm ignoring it from Room, the compiler cannot continue because it's the constructor that is checked first, thus failing all my other values to be set.

So, a small fix for this, is that make every variable a var instead of val and make our object nullable type. It's not a bad solution, but now I have to define a constructor, to tell Room that these are the default values from it: 


The solution

Perhaps it is not such a big deal, but when chances are, why not try a better approach?…

Let's get beyond null safety

Inspired by myself and perhaps some other people, who coded Java style in Kotlin. I have seen tones of articles which (mostly) highlight Kotlins null safety and nothing more. So that's it? If it was only for that I swear I would be still using Java with some null checks. Therefore, this article suggest what to use best in Kotlin as well as droping some everyday Java habits. 

What this article is not: A comparison between Java and Kotlin.  

Variables:

There is a lot of new things obviously but sharing what is important for me in variables is the lateinit and lazy implementation.


In case you never initialize the variable and use it, Kotlin will throw an exception indicating that the variable has never been initialized:

Let's jump into something fun, the lazy initialization, which basically throws us into one of the super powers of Kotlin: Delegated Properties. Delegated Properties is just a way of programming in Kotlin which must (or at least has to) be used. Think of delegation…

Dagger Multibindings saved my time

While the Android architecture made development simpler, we should always be aware of the Lifecycle and with that, the right way to provide ViewModels. Creating one ViewModel factory for each Fragment and ViewModel you have is really expensive, bad architecture, and too much unnecessary code.  Not to mention the fact that you should care about scopes, dependencies, components modules when using Dagger for DI.

You can have a simple "generic" ViewModel factory for all your app as a Singleton, with the help of Kotlin Reflection and Daggers Multibinding.

What is provided here is a class, which has a Map in the constructor and extending the ViewModelProvider.Factory. On the only method it has, we are just going to provide our own instance of the ViewModel we need, which is the key of the map, and when that dependency is available we are going to require its particular dependencies which are "stored" in the value of that map. We can place as many ViewModels as we need,…