I started writing on Medium in 2016 when I thought it made sense to share helpful info with other people on a platform to which everyone has access. This way you don’t need to promote your content; it is immediately available to everyone, as people say “under their fingertips”.
Continue reading “Why am I unsubscribing from Medium as a tech info source?”How did we get to an IT crisis in 2024?
We live in interesting times. We are doomed to live in this era where computers have replaced people, money has become a virtue, and the connection between ourselves is destroyed by the strong feeling of individualism. But no, I won’t be talking about these obvious things, I will talk about another thing happening in the IT sector. I mean the constant layoffs that have started since the COVID crisis and are continuing even today when thousands of people are losing their jobs and are left to help themselves … individually.
What makes me constantly think about these layoffs? Let’s say I am very close to such examples where highly skilled people are lost, CEOs we are wondering how to get out of the product rabbit hole and companies have made some awful staffing decisions that are still hidden from everyone’s sight. Recently, I figured out that the layoffs.fyi website stands next to my Github pull requests tabs and I just started searching for the reason: “Why?”.
Continue reading “How did we get to an IT crisis in 2024?”KAPT to KSP migration and Hilt
There is an issue with Dagger / Hilt when you migrate your project from the KAPT to KSP code generation plugin.
Continue reading “KAPT to KSP migration and Hilt”Downsides of Firebase Realtime DB for Android
There are a couple of downsides we figured out in our daily work with Firebase Realtime Database for Android and I would like to share them with you here. All of them revolve around using the provided SDK for Android. So let’s start.
Data listeners cannot be stopped
If you initiate a listener to observe some data like this one for example:
mDatabase.child("users").child(userId).get().addOnSuccessListener {
Log.i("firebase", "Got value ${it.value}")
}.addOnFailureListener{
Log.e("firebase", "Error getting data", it)
}
Then you may need to cancel it if your user leaves the screen where this data is presented. There is a cancel() method that you can call but unfortunately, this cancel method only removes the listener callback but does not cancel the operation going on in the background and lets it run until this completes.
Now imagine if you require a good big chunk of data for the screen and the user just does not want to wait because he has a 3G connection. You call cancel but the operation is still there in the background. You can verify logcat for that. What happens is that this operation still uses RAM memory that your app may need for something else and you can easily hit an OOM exception.
So for querying big datasets, it is best if you have a dedicated server that returns only the data that you need to work with.
Continue reading “Downsides of Firebase Realtime DB for Android”The challenges of server-driven UI on Android
Server-driven UI is not a new concept. Neither for Android, iOS, or the web. It is quite popular in recent years, especially with the introduction of component-driven architectures such as Flux / Redux and others. Now three projects ahead with server-driven architecture in place, I want to share with you some of the challenges that we faced, and the different approaches to solving them. And I will be really happy if you share your experience too.
Continue reading “The challenges of server-driven UI on Android”Local KtLint configuration for Android
KtLint & Detekt are tools that help us keep our code formatted in the same way and sometimes even help us spot errors before they are actually merged to master or develop.
Most of the CI integrations already include a detekt step before the unit tests are run. To avoid waiting for the CI, you can easily integrate ktlint as part of Git hooks. So every time when you decide to commit, Git hooks run and ktlint analyzes the committed files and prevents you from pushing until you fix your errors.

RecyclerView loses focus when scrolling fast … or how to use it on Android TV
We had a project where we were aiming to reuse the same codebase across mobile and TV. You have this care very often and there is this consideration of:
Should we use the Leanback Fragments?
The experienced Android TV developer
that is always ignored. We give the project a quick go and check how it works on the Android TV emulator and decide it is not worth the effort to work on TV specific codebase that may require additional devs to support it. And this is where hell breaks loose.
Continue reading “RecyclerView loses focus when scrolling fast … or how to use it on Android TV”Taming websockets with Coroutines, Clean Architecture and a library
Websocket integration is one of the biggest issues I had in my whole experience with Android. Why is it such a huge pain? There are several reasons behind that:
- Connection should remain stable no matter what – and we know how complex the Android lifecycle can be.
- Sending data can be a one-way operation without giving any result – did you succeed in sending it or did you fail? Only Server knows.
- Retrying connection or network requests can be tricky to implement – from pushing logic to interactors to having an internal logic inside a repository, be sure – nothing will work at 100%. Not even at 90% either.
- To get it right you need both frontend and backend collaboration. Nothing can be done if both sides do it separated from each other.
Android navigation library and TransactionTooLargeException
Let’s admit – the Android navigation library is a really cool thing but it has its own issues and drawbacks. One of the issues you can have is the TransactionTooLargeException. And here is how it happens.
Continue reading “Android navigation library and TransactionTooLargeException”Don’t forget about the difference between android:windowActionBar vs windowActionBar in your theme
What is the difference between this piece of code:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
</style>
and this one:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowActionBar">false</item>
</style>