Android and iOS are the leading mobile operating systems in the world. They have some similarities, but also some differences, that trigger strong opinions in the users’, but also developers’ debates. I’m an iOS developer for the past 8 years, and a big fan of Apple’s ecosystem. However, before those 8 years, I briefly did Android for around half a year. Fast forward to today, I needed an Android version of my Soccer Puzzles app. Instead of hiring someone, I’ve decided to give it a go myself. So in this post, I’ll summarize my experience of developing an Android app, as an iOS developer. I’ll try to be as unbiased as possible.
The biggest change since I’ve last touched Android, is definitely the language change. Now, Kotlin is the preferred language for developing Android apps. Kotlin is very similar to Swift, and it’s delightful for developing. There are some syntax differences, like let vs val, or func vs fun, but in general, it’s very easy to switch from Swift to Kotlin. For the more advanced features, Kotlin has coroutines for async programming, and that’s something I would love to have in Swift. On the other hand, Kotlin’s enums are not that powerful, but it has sealed classes. What I like more about Swift, is that it uses value types like structs and the arrays and dictionaries are value types as well. I will not go into details about the language differences, since there are already a lot of great posts available on that topic.
Since at the time of developing the app, Jetpack Compose was still in beta, I’ve used the standard imperative way of building Android apps. Of course, if I compare it with SwiftUI (which I’ve used for the iOS app), it’s quite a big difference, but that’s not a fair comparison. Instead, since I haven’t digged deep into Jetpack Compose (definitely on my todo list), I will compare it with UIKit.
Using the different kinds of layouts (relative, linear, constraint) in Android, is very flexible and straightforward. For example, one of the most important parts of the Soccer Puzzles app was dynamically drawing football formations. For more details on football formations, you can refer to my SwiftUI article. In a nutshell, the challenge is to draw player positions in several parts of the pitch (defence, midfield, strikers), in few different variations (4-3-3, 4-4-2, 4-1-2-1, etc).
LinearLayout, with its stack properties, works great for this use-case. Basically, the solution to draw the formations is not that different to using VStacks and HStacks in SwiftUI. In general, I really like the xml-based way of building UI in Android (although they now also have visual builder, but I haven’t used it that much). For most of the things, like moving things up or down, it’s more flexible than the constraint based layouts in UIKit.
Another argument for flexibility is that I was able to easily tweak the UI to build the basketball version of these puzzles series.
It’s also great to see that now (compared to 8 years ago), there’s a recycled list view, which re-uses the rows in a list, similarly to the UITableView on iOS. Using it over the standard list view, improved the scrolling experience a lot in my app. I can imagine Android developer reading this and saying “You don’t say?”.
Because of the very diverse ecosystem and different Android devices, there were issues that had to be fixed for different combinations of density and resolutions. Although I’ve tried testing on as many devices as possible, I’m pretty sure there are some devices where the UI might be messed up. That was always one big positive for iOS developers, and it still is.
One thing that I haven’t looked into are animations on Android. The iOS app has a lot of animations, most of them coming out of the box for SwiftUI. However, because of time restrictions, the Android app doesn’t have a lot of animations. Hopefully, in a future version.
I didn’t want to experiment much in an area I’m not that proficient at. I know that there are Android Architecture components, live objects, bindings and several app architecture patterns. However, I’ve decided to go with the classic MVC approach (unlike my iOS app, which uses MVVM). In order to prevent ‘god activities’, I was doing separation of concerns as much as possible. Using repositories, services, helpers and custom views, I’ve managed to keep the activities as light as possible. Probably not the most optimal way of structuring Android apps, but it worked for my use-case.
In terms of navigation, it was done with Intents, directly from the activities. There was no centralized router / coordinator, patterns which I usually use in iOS apps.
In terms of developer tools, I was surprised how fast the emulator now starts. Android Studio is very stable and has everything you need, at least for my project. I didn’t have any strange crashes, nor the IDE stood in my work in some way. I wouldn’t compare it to Xcode though, since I haven’t used it in a more advanced form. Gradle is great, the sync is always automatically started when you launch Android studio. No need to install Pods or manually integrate frameworks.
Creating releases is now simpler. Instead of creating APK, which is still supported, you can ship the app as Android bundle, which delegates APK generation and signing to Google Play. Google can store your signing key, in case you’ve lost it, which is handy. Another benefit is size reduction. Using Android bundles, in average, apps become 35% smaller. In terms of the Play Store itself, it supports several testing tracks, like alpha and beta channels. One useful thing is that you can experiment with app icons, to see which one would bring most installations.
Another cool thing that Android developers have is the app support library (now, there’s a new one, AndroidX). With it, developers are able to use new APIs in older versions of the operating system. That means that Jetpack Compose will probably have a fast adoption rate. If we had something like this on iOS, we would’ve been able to use Combine and SwiftUI on versions before iOS 13.
Developing an Android app was a good experience. I’ve learnt a lot from the “opposing” platform, which has a lot to offer. I still prefer iOS more, but that doesn’t mean that Android is not good. I will for sure come back to it, not just for updating my apps, but also to explore Jetpack Compose, and compare it with SwiftUI.