Okay Google, Show Me a Million Errors

07 Dec 2018 | tags: android

EDIT
Aaaaaaaand an update literally two minutes after I posted this: I was told that the data binding fix made it to the latest Android Studio Canary release.

I still opt to keep the config in my gradle file, but should be less necessary now.
/EDIT

Our team has been super busy lately.

Aside from working on two big feature changes, we have been working on merging our AndroidX migration. It is a lot changes!

If you have used data binding before, chances are you have come across this one pervasive issue: when any annotation processor fails, data binding throws up and you end up seeing a million errors in your logs.

We use data binding quite a bit in the app, so when a build fails (and there’s a good chance they will!) during this transition period, we see so many errors. So. Many.

There are plans to fix this though!

Anyway, we have so many errors that all I see are data binding issues and the real actual issue is invisible. I have no idea where to look first.

BUT! TIL that we have a way of actually seeing more errors!

If you’re using Kotlin, Kapt provides some Java compiler options:

kapt {
    javacOptions {
        // Increase the max count of errors from annotation processors.
        // Default is 100.
        option("-Xmaxerrs", 500)
    }
}

And for the Java variant:

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        options.compilerArgs << "-Xmaxerrs" << "500"
    }
}

Thank you so much to @Yigit Boyar for sharing this tip with me!


Ya Basic

02 Dec 2018 | tags: android

Over the last year or so, we have been writing a lot of Kotlin at work. There is a consensus within the team that we all like working with the language. It really helps our productivity a lot by reducing a lot of boilerplate, we can actively enforce nullability rules that makes business logic obvious, and having the option to make extension functions offers a lot of flexibility.

However, as a wise man once said, with great power comes great resposibility. There have been a few times where I see code written in a “Kotliny” way that I feel makes things look more complicated than it should be.

Take this one I saw at a recent pull request:

isSetUpDone?.run {
   if (shouldShowNotification()) {
       showNotification()
   }
} ?: showNotification()

I stared at that piece of code for five minutes, trying to figure out what it does. I read and re-read. Maybe I am too stupid to understand it. I asked the author – “Maybe put a comment in to figure out what this is doing? It is a bit hard to read.” I got a response: “Let me come over and explain.” He then proceeded to explain to me what run and ?: does (and I did not have the energy to ask him to stop mansplaining 🙄 ).

Now, my friends, that is not the point; and I have talked a bit about this in the past.


Complex != Genius

Just because something looks complex does not mean it’s ingeniuty at work. What if somebody else new joins the team? What if somebody else needs to make changes to this feature? What if the original author left the company and won’t be there to come over and explain anymore?

After talking to the author, we have come to the conclusion that what we wanted to do was call showNotification() only if all conditions are satisfied. So really, we can move isSetUpDone (which *is* one of the conditions!) to inside the shouldShowNotification() function, and we end up with a much simpler, much more readable implementation.

if (shouldShowNotification()) {
   showNotification()
}

If there is one thing I have learned from years and years of writing and reading code, it is that it takes a lot more time and effort to make things as simple as possible.

(via GIPHY)

We need to be careful that we do not fall into the trap of “How do I write this in Kotlin?”; that instead of leveraging the language, we end up abusing it.

I guess sometimes we get too caught up with making sure we can show off our chops and use these fancy new language features that we lose sight of what is really important – doing our bit in writing code that lasts forever.


Selectively Resetting SharedPreferences

16 Nov 2018 | tags: android shared preferences

I have recently been working on a feature that has a bunch of pre-conditions. Things like the user must be logged in AND the feature flag has to be turned on AND it only appears the first time the user lands on the screen.

Normally I would use the ADB plugin to Clear App Data and Restart, but doing so proves to be a bit too tedious in this case. I do not want to reset everything, just some things.

All I really want is to reset the “Has the user seen this screen before?” flag. I was in this same exact situation three years ago, and I wrote up a utility method to include in our dev drawer for handling this. I thought it was time to resurrect it and include it in my current project.

Massive thanks to Michael Evans for helping me with the Kotlin-isation!

This function is meant to be used within a dev or debug drawer. It aims to provide a quick way to reset individual SharedPreference files to their default values. It scans your app’s shared_prefs folder and lists the available files. You can then tick the box for those files you want reset.


Human-readable and neat 👌

Aside from the default file generated via PreferenceManager.getDefaultSharedPreferences(), the system does not really enforce a naming convention. They do recommend prefixing files with the application ID though!


Naming is hard

This function assumes that the SharedPreferences files your app owns follow this naming convention: MY.APPLICATION.ID_my_preference_file. Of course, there’s nothing stopping you from tweaking the current implementation to adapt to your needs!

For better readability, the application ID, the leading underscore, and the file extension are stripped out in the UI.

A neat thing to add here is put up a Toast or a Snackbar to confirm that the files were reset.

Anyway! Enough babble, enjoy the gist!