← Back to all posts

01 Xpense

What Xpense Actually Is

Xpense Dev Retrospective


Why This Series Exists

Xpense is an expense tracker I built for Android. It's on the Play Store right now, with real people using it to track real money. This series is me writing down how it actually got built, not the polished version, the actual version, including the parts I got wrong.

I'm writing this the same way I write the Java Fundamentals posts. Step by step, plain language, real examples. The difference is these posts aren't teaching a language from scratch, they're documenting a real app that shipped.


The Short Version

Xpense tracks expenses and settlements. You log what you spend, set a budget, and the app shows you where you stand for the month. There's a calendar view that colors each day based on whether you were under or over budget that day. It's a small app, but every piece of it had a reason behind it.

Where it lives: Package name com.hassanbukhari.xpense, built in Kotlin, backed by a Room database, with real users tracking real expenses on it.


It Didn't Start Like This

The first version of Xpense wasn't Kotlin, and it wasn't a database. It was Java, and it stored everything in a single JSON file plus a handful of SharedPreferences keys. That's it. No Room, no schema, no proper database at all.

That's not me being dramatic about my past code. It genuinely worked for a while. SharedPreferences is fine for a few settings. A JSON file is fine for a small list of expenses. The problem is that "fine for now" and "fine forever" are very different things, and I found out the difference the hard way later in this series.

v1.x

Java. A flat JSON file for expenses. SharedPreferences for categories and settings. A manual light/dark toggle inside the app.

v2.0.0

Kotlin. A real Room database. The app follows the system's light/dark setting instead of asking you to pick one.

Both versions shipped. Both had real users. The rewrite wasn't a rewrite for the sake of rewriting, it happened because the old approach genuinely ran out of road, which is exactly what the next few posts get into.


What This Series Covers

Roughly in this order: how an Android app runs underneath everything, how Xpense's code is actually organized, how the build system turns that code into an installable app, how the UI is built and connected to code, why the storage system changed and what went wrong during that change, how theming and dark mode work now, and finally how the whole thing got signed, built, and published to the Play Store.

One honest note: some of what follows is me explaining decisions that were correct in hindsight. Some of it is me explaining mistakes. I'm not going to pretend the second kind didn't happen.


Closing

Next up, before getting into Xpense specifically, a foundation post on what's actually happening when an Android app runs at all. Worth knowing before any of the rest of this makes full sense.

Next → 02 - How Android Apps Actually Work