, 32 tweets, 22 min read
For the past two years I've been recommending Android devs to avoid dagger.android. Now it's officially deprecated. Devs who listened to my advice won big time.

Today I reviewed the new official Dagger codelabs by Google. It's a complete disaster 🤦‍♂️.

Thread 👇
That's the link to the official Dagger codelab: codelabs.developers.google.com/codelabs/andro…
That's the answer provided to the question "Why Dagger?".

It's really poor.

I challenge Google Developer Advocates to explain in more details which kind of memory leaks can happen with manual DI (I'll call it "Pure DI" hereinafter), but will be prevented by Dagger.
And not just memory leaks.
What does "subtle bugs" mean? It's one of these terms that mean absolutely nothing, unless supported by specific examples.
What's "non-subtle bug" anyway? Something like this, maybe:

// THIS LINE CONTAINS BUG
<code>
But don't worry, you can get more info by following the non-exitent link.

All in all, the question "Why Dagger?", which is, considering the complexity of this framework, the foremost concern, is simply hand-waived through.
A bit off-topic, but still very well worth a mention, is the fact that "view models" used in the codelab have nothing to do with ViewModel "arch component".
I wouldn't be able to comment this fact better than that:
At some point, when field injection is being introduced, there is this odd paragraph which concerns View, Activities and Fragments.

If View here stands for android.view.View, then this paragraph is wrong. If it stands for Model-View-x view, then it's still wrong.
But maybe you don't want to take my word for that. That's fine.
Adam Powell, @adamwp, stated that Fragments aren't views on stage of Google IO 2016.

@adamwp More recently, during #AndroidDevSummit 2018, Ian Lake, @ianhlake, stated the same fact.

@adamwp @ianhlake So, it's not clear why would Dagger codelab contain this kind of misinformation and conflate view (whatever is meant by that) with Fragments.
@adamwp @ianhlake Why would a class named SharedPreferencesStorage have Context as a constructor argument? Wouldn't it make more sense for it to depend on SharedPreferences instead?
It surely would.
What we see here is called Law-of-Demeter violation.
@adamwp @ianhlake This technique of passing Context references around when not needed leads to lack of encapsualtion (because Context allows access to practically everything in Android) and, in extreme cases, to memory leaks (if wrong type of Context used).
Don't do that!
@adamwp @ianhlake I've never used either component factory or @BindsInstance in my projects. Two new annotations and an interface to place Context on the object graph (as this codelab suggests) is crazy.
Just pass it as constructor argument to one of your modules (others will "see" it too)!
@adamwp @ianhlake This is actually a good practice: always perform injection in onCreate(), before you call to super.onCreate().
It's true for both Activity and Fragment (unless the Fragment is retained).
@adamwp @ianhlake Question: why does this Activity need both UserManager and MainViewModel?
If view models contain all the domain logic, then there is no reason for this Activity to actively use UserManager. If Activity does use it, why it needs view model then?
@adamwp @ianhlake Ah, I see.
MainViewModel is used just to concatenate strings. And it doesn't really "tell" the Activity what to do - Activity is the one who polls it when needed. So much for MVVM reactivity.
Wait a second, why would strings be constructed in view model? I don't know.
@adamwp @ianhlake If you want to see some embarassed mumbling and hand-waiving, ask the author of this code why they need repositories if they already use view models.
@adamwp @ianhlake BTW, @Zhuinden , have you got an answer to the above question during Droidcon UK?
@adamwp @ianhlake @Zhuinden Ooops. Bad mistake. Sorry folks.
I meant that you don't need "use cases" and "repositories" together, but having "view models" with either of the above is alright.
So, just ignore the previous TWO tweets. I'm a bit tired and made a mistake.
@adamwp @ianhlake @Zhuinden As I said before, it's a good idea to inject in Fragment in onCreate(), just like you do in Activity.
As far as I know, you need to inject in onAttach() only if the Fragment is retained. Therefore, if you don't use retained Fragments, ignore this recommendation from codelab.
@adamwp @ianhlake @Zhuinden Ironic that the same folks who market ViewModel "arch component", didn't use it in this codelab and hint towards retained Fragments with the recommendation to inject in onAttach().
Maybe someone from Google Advocacy sends us a signal of distress this way? 😱😱😱
@adamwp @ianhlake @Zhuinden Component factory is a pure, unneeded and confusing boilerplate in this subcomponent. It does absolutely nothing, except adding complexity!
@adamwp @ianhlake @Zhuinden MORE PERFORMING AND SCALABLE 😍😍😍
On the second thought... Could anyone tell me a bit more about the performance and scalability issues? Maybe it'd be a good idea to share some numbers to support this claim.
Otherwise, it's just another meaningless hand-waiving
@adamwp @ianhlake @Zhuinden Have I already mentioned the excessive complexity associated with unneeded components factories that do nothing?
@adamwp @ianhlake @Zhuinden Following the same reasoning as before, we can just shut the application down and start fresh if the user logs out or unregisters. This will ensure that no "data specific to a logged in user" will survive.
Wait... maybe also re-install the app, just to be sure!
@adamwp @ianhlake @Zhuinden Folks, the idea of destroying objects to just clear some cached data is a bit non-optimal. You can just clear the data, you know.
@adamwp @ianhlake @Zhuinden What will happen if two weeks from now MainActivity will need to become accessible even if no user is currently logged in?
@adamwp @ianhlake @Zhuinden That's an abomination! You have Dagger component injecting UserManager, and UserManager manages another Dagger component?
Good job! You've just created the tightest coupling between code and DI framework I've ever seen (and I've seen a lot).
@adamwp @ianhlake @Zhuinden Sure enough, this "elegant" solution requires a bit of comments to be understood. And a bit of nullability. It's great to see the full power of Kotlin's null-safety in action!
@adamwp @ianhlake @Zhuinden And a bit more ugliness in MainActivity to support this original design. Honestly, first time I see "conditional injection". That's an innovation right there!
@adamwp @ianhlake @Zhuinden But there is a disclaimer, so everythign is kosher! It basically says:

this approach is risky, so go on and ADD SPLASH SCREEN TO YOUR APP JUST BECAUSE YOU SET UP DI ACCORDING TO OUR RECOMMENDATIONS 🤯🤯🤯

Your product manager and users will surely understand the necessity.
Missing some Tweet in this thread? You can try to force a refresh.

Enjoying this thread?

Keep Current with Vasiliy Zukanov

Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!