Bootstrapping Android Development: A Survival Guide

Developing Android applications seems like it should be fairly straightforward if you believe the glossy marketing by Google and others. It’s certainly possible to just follow the well-trodden path, use existing templates and example code – or even use one of those WYSIWYG app generators – to create something passable that should work okay for a range of common applications. That’s a far cry from learning general Android development, of course.

The process has changed somewhat over the years, especially with the big move from the Eclipse-based IDE with the Android Development Tools (ADT) plugin, to today’s Jetbrains IntelliJ IDEA-based Android Studio. It’s fortunately still possible to download just the command-line tools to obtain the SDK components without needing the Google-blessed IDE. Using the CLI tools it’s not only possible to use your preferred code editor, but also integrate with IDEs that provide an alternate Android development path, such as Qt with its Qt Creator IDE.

Picking Poison

Both Qt Creator and ADT/Android Studio offer a WYSIWYG experience for GUI design, though the former’s design tools are incomparably better. Much of this appears to be due to how Qt Creator’s GUI design tools follow the standard desktop GUI paradigms, with standard elements and constraint patterns. After over a decade of having wrangled the – also XML-based – UI files and WYSIWYG design tools in ADT/Android Studio, it never ceases to amaze how simple things like placing UI elements and adding constraints love to explode on you.

The intuitive Android Studio WYSIWYG experience.
The intuitive Android Studio WYSIWYG experience.

Somewhat recently the original Android API layouts also got ditched in favor of the ‘refactored’ AndroidX API layouts, with apparently now this Jetpack Compose being the (high-level) way to use. Over the years of me having developed for Android, many APIs and tools have been introduced, deprecated and removed at an increasingly rapid pace, to the point where having Android Studio or the CLI tools not freak out when confronted with a one year old project is a pleasant surprise.

Designing GUIs in Qt Creator's Designer mode.
Designing GUIs in Qt Creator’s Designer mode.

Although Qt isn’t the only alternative to the Android Studio experience, it serves to highlight the major differences encountered when approaching Android development. In fact, Qt for Android offers a few options, including building a desktop Qt application for Android, which can also use the Qt Quick elements, or including Qt Quick within your existing Android application. For Qt Quick you want to either create the UIs by hand, or using Qt Quick Designer, though I have so far mostly just stuck to using Qt Creator and liberally applied stylesheets to make the UI fit the target Android UI.

Whichever way you choose, it’s important to know your requirements and take some time to work through a few test projects before investing a lot of time in a single approach.

The Build System

No matter what approach you choose, the build system for Android is based on what is objectively one of the worst build automation tools conceivable, in the form of Gradle. Not only does it take ages to even start doing anything, it’s also agonizingly slow, insists on repeating tasks that should already have been completed previously, provides few ways to interact or get more information without getting absolutely swamped in useless verbosity, and loves to fail silently if you get just the wrong Gradle version installed in your Android project.

Did I mention yet that the entire Gradle tool is a permanent fixture of your Android project? Android Studio will want to upgrade it almost every time you open the project, and if you don’t use an IDE like it which automates Gradle upgrades, you better learn how to do it manually. Don’t forget to install the right Java Development Kit (JDK) either, or Android Studio, Gradle or both will get very upset.

If your IDE doesn’t pave over many of these inane issues, then getting familiar with the Gradle wrapper CLI commands is right on the top of your list, as you will need them. Fortunately sticking to an IDE here tends to avoid the biggest pitfalls, except for having enough time with each build session to fetch a coffee and go on a brisk walk before returning to address the next build failure.

There are no real solutions here, just a call for perseverance and documenting solutions that worked previously, because you will always encounter the same errors again some day.

Test, Debug And Deploy

Creating a new virtual Android device.
Creating a new virtual Android device.

Even if you have built that shiny APK or app bundle, there’s a very high likelihood that there will be issues while running it. Fortunately the one advantage of JVM-based environments is that you get blasted with details when something violently explodes. Of course, that is unless someone screwed up exception handling in the code and your backtrace explodes somewhere in thin air instead. For the same reason using a debugger is pretty easy too, especially if you are using an IDE like Android Studio or Qt Creator that provides easy debugger access.

Logging in Android tends to be rather verbose, with the LogCat functionality providing you with a veritable flood of logging messages, most of which you want to filter out. Using the filter function of your IDE of choice is basically essential here. Usually when I do Android application debugging, I am either already running Qt Creator where I can start up a debug session, or I can fire up Android Studio and do the same here as at its core it’s the same Gradle-based project.

 

The NymphCast Player Android build, with default skin.
The NymphCast Player Android build, with default skin.

Of course, in order to have something catch on fire you first need to run the application, which is where you get two options: run on real hardware or use an emulator. Real hardware is easier in some ways, as unlike an emulated Android Virtual Device (AVD) your application can directly access the network and internet, whereas an AVD instance requires you to wrangle with network redirects each session.

On the other hand, using an AVD can be handy as it allows you to create devices with a wide range of screen resolutions, so it can be quite nifty to test applications that do not require you to connect to externally via the network. If you want to know for example how well your UI scales across screen sizes, and how it looks on something like a tablet, then using an AVD is a pretty good option.

Some hardware devices are also quite annoyingly locked-down, such as Xiaomi phones that at least for a while have refused to allow you to toggle on remote debugging via USB unless you install a SIM card. Fortunately this could be circumvented by clicking through an alternate path that the Xiaomi developers had not locked down, but these are just some of the obnoxious hurdles that you may encounter with real hardware.

With that out of the way, deploying to an AVD or real device is basically the same, either by using the ‘Start’ or similar function in your IDE of choice with the target device selected, or by doing so via the command-line, either with ADB, or via the Gradle wrapper with ./gradlew InstallDebug or equivalent.

This will of course be a debug build, with creating a release build also being an option, but this will not be signed by default. Signing an APK requires a whole other procedure, and is honestly something that’s best done via the friendly-ish dialogs in an IDE, rather than by burning a lot of time and sanity on the command-line. Whether you want to sign the APK or app bundle depends mostly on your needs/wants and what a potential app store demands.

Ever since Google began to demand that all developers – including Open Source hobbyists – send in a scan of their government ID and full address, I have resorted to just distributing the Android builds of my NymphCast player and server via GitHub, from where they can be sideloaded.

This NymphCast server is incidentally the topic of the next installment in this mini-series, in which we will be doing a deep dive into native Android development using the NDK.

5 thoughts on “Bootstrapping Android Development: A Survival Guide

  1. Um.. I’m not sure what was the goal here. Using QtWidgets (the “classical”, non-Quick UI) makes little sense on a touch-based device. Yes, you can make apps, you can probably even make apps which will somewhat resemble other Android apps, but the experience would be painful – for the developer and likely the user as well.

    QtQuick is way better in this regard, it provides nearly unlimited styling possibilities and a very nifty GPU-based rendering system. Various builtin widgets are designed to support touch interfaces natively.

    For non-GPL apps there is also the problem of licenses. Qt expects you to buy the (very pricy, compared to alternatives) commercial license for Android/iOS development. LGPL-based Qt might be suitable for distribution in the Play Store, but it requires a lot of handwaving and crossing fingers.

  2. Great article! I have dabbled with Android dev occasionally, mostly for personal projects in the form of small utility apps to do something trivial (like send a simple UDP broadcast packet or scan for BLE advert).

    I have always used android studio for my UI needs, and like most people have found it difficult to get the hang of. I was just getting familiar with the XML based version when they introduced the “Compose” system, which I absolutely have no plan of learning.

    I just need to make a small app once every 6 months, I’m not going to learn the ins and outs of Android. Conversely I am proficient with Qt5 for making small UIs on my computer so I’ll give Qt for Android a go. It SURELY cannot be worse than the vanilla experience

  3. i haven’t had luck with the commandline-only installation in a long time. in fact, the big transition in my mind isn’t eclipse -> whatever, but rather ant -> eclipse, because ant was the last one that i successfully installed the commandline-only tools.

    these days, i just install android studio and use it to create an empty project and then i don’t use android studio again until next time it needs to update. and fwiw it’s actually easy to sign an application from the commandline, though add it to the list of things that see pointless churn.

    i really related to the frustrations in this article. this sentence is gold: “There are no real solutions here, just a call for perseverance and documenting solutions that worked previously, because you will always encounter the same errors again some day.” !!!!!!!!!!!!!!!!

    i absolutely detest the mess they’ve made of the compatibility libraries. they had a pretty decent set of idioms for backwards compatibility a decade ago, but they completely abandoned it over and over again. compatibility methods is one of those things you really can’t reinvent without defeating the whole purpose! so these days, i don’t even know which API i’m supposed to target. and i know if i pick one, it will be broken soon. absolutely nothing that isn’t getting broken on the reg.

    the “you won’t be able to sideload in 2027” fake news is nothing compared to the realities laid out in this article, if you want to know why android is moribund. android development today is as bad as windows ever was. and android is as ubiquitous and unavoidable as windows was 30 years ago. it’s really bad. google really is the new microsoft. and it’s a real bummer because, like i said, 10 years ago, android was looking pretty good.

  4. This… is not how you write modern mobile apps. Ignore everything the author suggests. Maybe fine for a pet project, but not to be used in production under any circumstances.

    Also Gradle is sorely misunderstood. Gradle is just a dependency engine, and a pretty good one at that. It’s all the quirky undocumented plugins that make working with gradle a nightmare.

  5. I thought there would be suggestions of an alternative for gradle. Sadly, seems everybody is still in the same ( sinking ) boat. All the rest ( Android Studio x IntelliJ x Qt ) could be learned easily. But dealing with gradle makes one question if it is worth it ( every time ) .

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.