Among the dozens of small-app assignments we reviewed, the following misconceptions and “poor practices” tend to repeat a lot

Disclaimer

“Poor practices” are only poor practices when you don’t understand what you are doing surely and deeply. When you do, any practice can be a good practice!

Scope

In this article, I’ll focus on the primary use case of ViewModel for 90% of app screens: fetching and displaying some data. For secondary use cases such as handling button clicks or other user inputs, I believe that the same points hold true, but that deserves a separate article.

A) When to start fetching data?

Do: Use Kotlin’s init {}


The “auto-refresh” convenience Room’s RxJava (Flowable) integration gives you does come with a couple of caveats

Problem #1 UI is refreshed too many times

Given a view that renders data from stream that reads a particular DB tables, how many times will it update itself if old records are cleared and then new records inserted and/ or updated one by one?

N times, with N being the total number of write operations!

Not only it is an expensive operation but it can cause deteriorated UX e.g. loading animation comes and goes flashing too many times

Remedies

  • Group DB write operations into a @Transaction when possible
  • Use distinctUntilChanged() downstream…


The code

1 activity app with 1 presenter. Full source code is here

MainActivityComponent

@Subcomponent(modules = [MainActivityComponent.MainActivityModule::class])
// @PerActivity
interface MainActivityComponent {
fun inject(mainActivity: MainActivity)

@Module
class MainActivityModule(private val mainActivity: MainActivity) {

@Provides
// @PerActivity
fun presenter(catRepository: CatRepository): MainPresenter {
return MainPresenter(catRepository, mainActivity)
}
}
}

PerActivity scope

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity

Scoped dependencies

There’s a reference to the presenter in the generated code for the MainActivityComponent, allows Dagger to clear it automatically (when the activity is destroyed by the OS or by you)

DaggerMyAppComponent

private final class MainActivityComponentImpl implements MainActivityComponent {
private Provider<MainPresenter> presenterProvider; // <-- Reference here

private MainActivityComponentImpl(…


One upon a time, there was a singularity named :app module. Then came the smaller monoliths, namely :persistence, :networking and :models

Photo by Clay Banks on Unsplash

Why layers monoliths is a mistake?

  • They are still monoliths, albeit smaller than :app
  • All the problem that applies to :app still applies to :networking , :persistence and :models while you get none of the benefits modularization brings

Benefits of modularization

  • (Incremental) build time
  • Small and focused module — more productivity while working on a particular feature/ product
  • Features/ products are more self-sufficient and less inter-dependent so more flexibility in design, implementation and testing
  • Dynamic delivery of modules

More details in Jeroen’s article 👇

Why is it the greatest mistake?

  • The Internet is filled…


Photo by Ed Leszczynskl on Unsplash

Problem

Even though Proguard and R8 removed the unused code for you at release time, you should still make effort to remove dead code to reduce confusion, increase productivity of your everyday work and onboarding.

Solution

For starter, none of the static code analysis tools (SonarQube, CheckStyle, Pmd, Findbugs, Android Lint) I know does the job.

Since Proguard and R8 removed unused classes, I followed the instructions here and generated and generated an usage.txt file

  • Add -printusage to your proguard.pro file
  • Run ./gradlew app:minifyReleaseWithProguard or ./gradlew app:minifyReleaseWithR8

But the usage.txt file is big and I can clearly see some classed that are…


Photo by Tierra Mallorca on Unsplash

Imagine you went to meet your Tinder date and were informed on the spot that John or Mary or both were gonna join you presently. Replace Tinder date with your credit card application and and voila! Equifax and TransUnion are gonna enter your life and never leaves, forever ruining your relationships in a creepy way

Surprise surprise!

My first bank account in Canada was frozen out of the blue in June 2020. For more than 3 months, I had never been offered anything more than “one of the credit bureaus put a restriction on your files”.

Mistrust and verify

My credit started at below 650…


Given a list of Employees, find the average and sum of salary for each department.

You don’t have to be a Kotlin-programmer or any programmer to complete the following 4 tasks, just a curious mind and a love for numbers will do

Each Employee has the following properties:

  • Name
  • Department
  • Salary
  • Title

Does that sound familiar? I’m sure it does to all of us who have been through the 101 tutorial for Excel and SQL.

Buckled up as today we are going to learn how to achieve the same tasks with Kotlin aka.


Recently, when doing a small coding challenge in Kotlin I was faced with the choice of mutableMapOf() vs. HashMap()

Photo by Marc Sendra Martorell on Unsplash

Being a Java old-timer, I first went with HashMap() or hashMapOf()

But then all the Kotlin tutorials start with mapOf() and mutableMapOf() ?

Afterwards, I had some interesting discovery to share here:

Behind the scene, both mapOf and mutableMapOf use Java’s LinkedHashMap data structure

Utimately, the comparison between mapOf, mutableMapOf() and HashMap() is down to LinkedHashMap vs. HashMap in Java.

These are the 2 most popular implementations of Map (or Dictionary or Hashtable if you will) data structure in Java. …

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store