Image for post
Image for post

There are three things I do every-time I start a codebase that I know that I will be maintaining for the long haul.

  1. Order a Rubber Duckie on Amazon
  2. Familiarize myself with the latest developments in the forever ongoing UI architecture wars (e.g. Mortar and Flow, Conductor, Scoop, and the newest challenger Jetpack Compose) before ultimately giving up and just relying on multiple Activities (yup, i’m that kind of Android dev).
  3. Set up an assertion framework

Enforcing Invariants through assertions

Invariants are some of the best ways to maintain your sanity as a coder. They are essentially unit tests that are always executing since they run during the execution of the production software and will save you a lot of debug time when used correctly. …

Image for post
Image for post



/*** Calls the specified function [block] with `this` value as its argument and returns its result.*/public inline fun <T, R> T.let(block: (T) -> R): R = block(this)


  • called object passed in via argument
  • return type is whatever the lambda returns

typical usages

  • convert from one type to another
  • handling Nullability
// using 'let' to convert from one type to anotherval answerToUniverse = strBuilder.let {    it.append("Douglas Adams was right after all")    it.append("Life, the Universe and Everything")    42}// using 'let' to only print when str is not nullstr?.let { print(it) }



/*** Calls the specified function [block] with `this` value as its receiver and returns `this` value. …

Image for post
Image for post

As Halloween flies by and we dress up as ghouls, ghosts and other things that go bump in the night, it occurred to me that one of the the scariest things to an Android developer (outside of Out Of Memory exceptions, of course) are unexpected breaking changes in an API when you upgrade a dependency. There are a few reasons that this can happen. Maybe the author has decided to take the API in a different direction. This is one of the good reasons. Unfortunately, there are a lot of bad ones too. One of the worst reasons breaking changes can happen is because the author of the library removed members from API that you depended on but that they never intended for you to have access to in the first place. In this post, I want to look at why utilizing Kotlin at first seems to help with this issue and where it falls short. …

The “one click build” is a golden standard that developers would love to achieve. Whether it is making debug builds, builds for QA and especially release builds, the simpler the release process the better. Some even consider it a criterion to measure the health of a codebase by. And the reasoning for this is straightforward. Less steps equate to less time and, more importantly, less chance of error. …


Automated tests are king. Reading any modern programming book like Working Effectively with Legacy Code and it is obvious to see why coders just can’t get enough. Usually, the main focus of our automated tests is on the correctness of our business logic. However, there is one form of automated testing that is maybe too oft neglected and that is the measuring of your app’s Jank. Jank is the term that is used when your app drops frames usually due to poor performance. Analogous to how unit test provide quick feedback about correctness, wouldn’t it be great if we had performance test that provides quick feedback about Jank (or hopefully, lack thereof)? …

Image for post
Image for post

We’ve all been there. It is 5:58 on a Friday. Your office is empty save you, a few of your coworkers, and, of course, your Project Manager. She looks on earnestly as she awaits your fix for the production bug that is stopping users from being able to place orders, you know, the most critical portion of your app. And finally after what seemed like an eternity of searching, you find the problematic code. And you see the problem. This code is crap. For whatever reason (justified or not), the previous developer left this code in a hard to read, error-prone state and now you have two choices: either spend the six hours to architect and re-write this entire section of code while your users, and ultimately your brand, suffer as they have to wait an entire weekend for a fix or spend 10 minutes building on top of what is already there allowing you to push out a build that makes your stakeholders and users happy. In the scenario above, it is likely you will choose option 2. Ship the code as is with your fix on top of it and make a note to yourself to refactor this sometime next week. …

Crash reporting is an invaluable tool and with the assortment of crash reporting tools to choose from, there isn’t any reason your app shouldn’t taking advantage of them. Even the most basic integration of Crashlytics provides extraordinary insight into how your application is behaving in the wild. However, what if we went beyond the basic setup? With a bit more configuration, we can obtain a greater Return On Investment (ROI) from our crash reporting implementation and gain more insights into our application.

Tip #1 — Include the state of the codebase in your error reports

Performing Root Cause Analysis (RCA) for an issue within an application is hard enough when you know the exact commit where the issue is occurring. But what if you get a new crash report on a version of the app you pushed out months ago? Let’s remove any ambiguity from our error reporting by including the Git Hash of the code in which the exception actually occurred. Custom Keys, which allows you to include key/value pairs with your crash reports, is the perfect solution for adding the Git Hash to the error report. …


Andre Perkins

Android Developer, Television Enthusiast, Bad Joke Connoisseur | @Muru | New York, NY

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