Aki Rautio

Reflections on developing Android application as a web developer

January 9, 2021

For a long while, I have had an idea for an android application. There is a garage in my housing complex that opens up by calling a specific mobile number. Often my mobile isn't close by when I would need to open the gate, so I thought of creating an app to solve this issue.

Starting to develop for a new platform is relatively time-consuming compared to results, so the project has been stagnating for a while. When I stumbled on the new Jetpack Compose toolkit for the UI creation, my interest got up again since the project would also give insights into where the android development is going.

Most of my software development experience comes from technologies, frameworks, and libraries used to build user interfaces for web applications so building a mobile application isn't too far from what I have used. Having specific tools and framework features to a specific platform are still something I haven't used to so here are my findings.

First setup

Compared to web development, one of the significant differences is to have a proper IDE (Android Studio). IDE tackles almost all aspects of software development from the code versioning to create, evaluate, and debug the application. It also standardizes the underlying tools and hides them very well. For instance, as long as it works, you don't have to know what kind of commands Gradle needs when building an app. Having more focus on code and the features than steps to get the application working reduces the time to get something tangible shown on a device.

Android Studio

With all the helpful tools IDE provides, it's really easy and simple to start doing the first project. Right now this applies to all but Jetpack Compose which is an alpha state and needs additional packages to the project. Fortunately, Google offers a pretty straightforward guide on how to proceed, so it's not too much trouble

In total, I think it took something like 1-2 hours from downloading Android Studio to get the first application run on a device with all needed libraries (including Jetpack Compose) ready to use. In my opinion, that isn't too much considering that the same process without IDE would probably take a full day. I was also pleased with all the features provided by IDE, such as the red line indicator from errors and a wide range of automated suggestions to make code more readable.

Writing Kotlin

A new programming language, Kotlin, is a second key difference to my standard development workflow. The difference isn't too big, coming from Javascript and Typescript. Compared to Java Kotlin feels a lot more readable and easier to comprehend so development feels more satisfying.

Kotlin

Model View ViewModel design pattern

As part of writing an Android software, I got to write ViewModel classes which are part of the Model View ModelView design pattern. This seems to get a lot of popularity in user interface applications lately. SwiftUI on iOS is also using MVVM and VueJS and Angular both promote separation of data and view components with their implementation. MVVM doesn't too much differentiate.

A summary for this pattern is about handing UI layer and data layer separate and connecting them by ViewModel. This wasn't anything too new different from what I'm used to but having supportive elements to implement this eases up the work.

Model View ViewModel

I ended up splitting the data parts even further roughly based on Josip Šalković's article. This was especially useful when using Room as a local database since database calls were handled separately from the real logic and ViewModel code ended up being a pretty high level.

Dependence injector

Dependency injection as a term is rarely used on React even though the mechanism is more or less available in there too. The idea is that dependencies can be defined as input parameters instead of defining them inside the component to give the flexibility to change the dependencies when needed. In my view, the greatest advantage is the simplicity of writing the tests, as injected dependencies are much easier to mock than closely coupled dependencies.

My choice was to use Hilt as a dependency injector because that's what the android documentation recommends. The base setup is simple and easy but Hilt does so much automatically that it's hard to comprehend what's going on behind. This isn't a big issue until something isn't working exactly as expected.

For example, I had a Repository class that didn't have dependencies so I thought of doing it as a normal class. All seemed to be good until I started to build the application and got some weird build errors. It took quite a while to figure out that the cause was missing an empty injection setup.

Although I like the simplicity that Hilt provides, it will eventually trigger bugs that take a lot of time to identify since too much magic happens behind the scenes. It would be much more work to do this manually, so I will continue to use Hilt, even with obvious downsides.

Jetpack Compose

One of the most familiar parts of the android developer surprisingly was UI development with Jetpack Compose. The idea is almost identical to React where each UI component is a function and the whole UI is composed of those smaller UI components. Android also has mutableStateIF function that handles the internal state. The IDE also has a visual preview from the components that have @Preview annotation and this feels very much like what Storybook has been.

This certainly is another UI pattern getting more popularity. Besides Jetpack Compose, SwiftUI has a very similar type of pattern to write the UI, and more or less all web frontend frameworks are using the same pattern nowadays. I have been using this in React for quite a while and it certainly gives a huge boost to development compared to other development patterns in frontend work.

To be said Jetpack definitely isn't fully ready yet (hence the alpha state) and that certainly can be felt.

  • Sometimes the compiler decided to produce random errors that went away after the entire application was rebuilt. The visual preview also stopped working in the end though I think it was due to an old version of the Android Studio.
  • There is also some limitation on component level and on my two-month journey to finish the application, the API got a huge amount of significant changes.

Nevertheless, I can already feel how this will make UI development a lot easier in Android and it will make a transition between platforms a lot easier since there is no need to learn new patterns.

Quirks of developing to Android

Jetpack wasn't the only part where things weren't as planned:

  • Permissions are something that I'm not used to handling and finding the right flow took some time (+ it's still in progress)
  • Not all features are well defined or give an understandable error message. For example in android 10 opening activity in the background just doesn't work. No error but it just doesn't open anything.s
  • I tested the application with a few different android versions but testing the application with every major android version and hardware provider like Samsung would take a huge amount of time.
  • Android Studio is automating so many things that many tasks feel like magic. It also gives a feeling that something will break at any minute.

Adding an application to Play Store

Once I got the first version of the application ready, it was time to release it in the Google Play store and that was quite a journey. As a web developer the software tends to be released as is so once you have finished the development, it's ready to be deployed and marketing can start.

With Play Store, App needs have good descriptions, screenshots, and the marketing material beforehand and there is quite a huge amount of mandatory content to fill out even before you can submit the app package. And once everything is ready, the application will be reviewed before it's available for the customers. This will make the whole update and bug fix process a whole lot different from web development because it will take hugely longer to get the bug fixed in an application.

Findings

The most significant finding from this experience is that developing to different platforms isn't that much different anymore as it used to be. The patterns to build UI and architecture the application starts to resemble each on both web and native android even though the tools themselves may offer different features. This should make developers' life easier since knowledge from one platform can be at least somewhat utilized to other platforms.

I would also see that the patterns I used in an android application gave me a better ability to use them more on the web and especially with React that gives the freedom to experiment. For example, MVVM design pattern can be created by simply separating the data and view layer with a middle layer that ensures rerenders when data behind changes.

While there were a lot of similarities between platforms, the distribution with the mobile application is vastly different from the web. Having an application store in between the client and developer is a whole lot different experience than distributing the result straight to the user. This also brings with a bunch of new challenges to be solved like how to ensure that changes services are taken into account on multiple client versions or how to distribute bug fixes. George Orosz's blog post touches on these topics very well so I highly suggest reading his views.

While VSCode is a good text editor, I definitely will miss many more IDE level features from Android studio. One of these is the storybook-like component view next to the code. On the other hand, having used to getting strict autoformatting on save with Prettier was something I missed while writing the app.

If you are interested to see the result from this journey, the CallGates app is available on Google Play.

Comment or ask about the post in Dev.to