Busted is a platform that I have been developing casually since 2017. It's purpose is to coordinate with the many different independent services I have running on my network and provide detailed information on the current state of things. Additionally whenever a manual action needs to be taken for maintenance, it will coordinate those actions. For example, I could display a list of running Docker containers in a mobile app and if one container is reporting a status check failure I could restart it from anywhere in the world with a simple click.
Building out all of this has been an iterative process. Initially this was where I got my feet wet with spinning up a Docker container for hosting my media server in a more portable way. Then once that was up and running I added more services that complimented the media server and eventually my own services to provide custom behavior.
The first and most long running service is the foundation to the Busted platform, the Busted API. It is built leveraging the Spring framework to provide a nice interfacing layer for coordinating with my other services. Since they can and do have vastly different API implementations I felt that rolling my own layer here could allow me to isolate that adaption into one place and even more importantly, isolate those services from the outside world.
Since this is an internal tool and Android has been my platform of choice for a decade I decided to build out the frontend for it alone. With the API being stable Busted could be used for testing out other platforms in the future, but for now this is it.
The first iteration of the Android client was built in Java, leveraging the MVP design pattern. It was implemented using the common tools of trade at the time of RxJava2, Dagger, and Butterknife. The design took inspiration from some of my previous internal projects but it was all pretty cut and dry, I wasn’t trying to win any design awards here. Below are some screenshots from the client.
Normally I’m not one to rewrite something just because it is using old patterns or technology, but this time is a bit different. The last few years Google has been pushing their new layout system Jetpack Compose pretty hard. Those who use it cast aside the old ways like they are inferior and I am susceptible to a little bit of fear of missing out from time to time. So I decided to dip my toes into it by diving headfirst into the deep end with no flotation device. With everyone I knew that knows Compose on holiday, I loaded up Android Studio and created a new project.
The first step I decided to do was document my existing Busted API using an OpenAPI 3.0 config and generate a client integration via SwaggerHub. This provided an honestly bad implementation to interface with but so far it has been functional enough that I have not bothered to write my own yet. With a couple wrapper classes I could hide away their bad auto-generated code. After configuring authentication I was effectively ready to start building out my user interface.
Building with Compose overall is frustrating
All of the institutional knowledge that we have obtained for building user interfaces can largely be thrown out. Components are named just different enough that they are unintuitive, and some things are named the same but can act differently depending on the context or even order of operations. For example, margin and padding back in the xml layout system had clear and defined behaviors. Both of those concepts are now combined into simply padding and depending on if you add a background before or after you set the padding it will display differently.
I based my Compose integration upon the JetNews sample provided by Google and leveraged M3 components. At this point in time this is the absolute bleeding edge of what they recommend. Building out all of the top level sections I was able to fully immerse myself into the new layout system. I have a single Activity + ViewModel design with multiple sections all backed by a single state representing my view layer. Coordinating side effects like dialogs and snackbars can be a bit convoluted but that is what you get when you have a single state generating everything.
This exercise was a good one, but I don’t think this is the final iteration of the layout system. As the system matures over time we will be able to build amazing things with it. I will not be casting the xml layout system aside for now, but for non-production code I will also be using Compose. I still have quite a bit of work left to go on this project alone.