Update 10/13 – Due to the overwhelming response, some updates were made to clarify my positions on things. Also, take note, there’s plenty to like about Android development, too! (No provisioning profiles, amirite?) I only focus on the warts because I’m explaining why I leftAndroid.
This week marks my final week of working on Android. I’ve had my ups and downs with it, but I’m excited to retire from Google’s mobile platform.
OK, story time…
How I Got Started With Android
I began dabbling with Android about a year after boarding the iPhone train. Prior to that, I’d spent a couple years writing Blackberry and Java ME apps. (What are thoooooossseee?) Having become comfortable with iPhoneOS (that’s what it was called back then, look it up…), Android was starting to take off and I was curious to learn it. I taught myself for a while and then took a course from my then co-worker, and now world renowned author, Tony Hillerson.
Around that time, I got tasked to work on an Android bank project with a platform superfan, Josh Jamison. It was my first chance to do daily Android work and…it…went…poorly. The tools were in their infancy and Eclipse was downright awful compared to Xcode. Everything was slower. Compiling, Running. The emulator was freaking useless and Genymotion didn’t exist yet. I didn’t have an Android device of my own to test with, either. I’d been so comfortable with iPhone’s environment and Android just felt so raw.
It was a miserable experience. No matter how hard I tried, I just couldn’t get in a groove. I was an awful Android developer until mercilessly I was moved to another team. (I don’t recall being fired from it, but I wouldn’t be surprised if I was.)
Over the next couple of years, I dipped back in and finally acquired my own hardware. (A Nexus S.) The tooling was improving and re-learning the platform gave me new insights and I started to grok things a lot better. After moving on to Double Encore, I started working on more Android projects and even led one. (Whoa.) Android developers were still a rare breed, but the community was drastically improved.
Soon after, I embarked on my own and turned Rapture In Venice into a full-time consulting studio. To my surprise, I was getting contacted for Android work a little more than I expected! Of course, I took it on.
In the five years Rapture In Venice has existed, I’d estimate I’ve spent half that dedicated to Android. I’ve done co-location work for it, built Android apps alongside iOS implementations, ported apps to Android from iOS, and even found time to create my very own app for the Google Play Store.
Even more shocking, I switched to a Samsung S6 edge+ as my personal carry for about 6 months!
That leads me to today…
My Retirement From Android
My decision to officially abandon the platform didn’t happen overnight. In fact, it’s taken two years of consideration and false starts.
For a long while, the “hybrid” mobile developer (knowing iOS and Android) was a rare sight. I took pride that I could do both. As a consultant, I could sell myself on someone who could write both versions of an app for a client. My fluency in both made me an asset for porting jobs. I relished it.
As time wore on, more developers were trying out both sides of the aisle. True hybrids are still rare, but there are many developers who have familiarity with both platforms now. Still, why would I leave one behind? I’ll tell you why.
Over the last couple of years, the unsettling feeling that I’m becoming a mediocre developer for each platform has crept over me. While it’s not true, and I have confidence in both, that feeling comes from the fact that I can only be half-engaged in each community. With each major conference, I can only watch a subset of the talks. With each new feature added to the platforms, it’s 50% harder to remember it all. I miss out on some new concepts while learning others. Even the basics have become unsteady.
Take, as an example, the simple concept of shared user preferences. iOS and Android both support this with NSUserDefaults and…SharedPreferences I believe? It’s funny, I always forget the name of it and have to try a couple autocompletions to recall it. Which one can store arrays? (It’s iOS.) Which one can store data in different buckets? (It’s Android.) Is it setBoolean or putBoolean? Do I call synchronize or commit? (Or apply now?) It’s hard to enough to remember an API clearly, let alone when you’re using two very similar API’s for two very similar platforms.
It’s just gotten too much and it’s hard to keep steady as an expert in both. On top of that, the value of knowing two platforms isn’t as helpful as it used to be. Sure, if I’m lacking work, I have two avenues to find more, but it’s not feasible for me to do both platforms for one client. They can simply use two resources at once nowadays. Apps aren’t as small as they used to be either, so there’s no value in my doing both.
The day-to-day of switching between platforms is also difficult. I’m currently finishing up a project where I’m doing maintenance on both apps for a client at the same time. I’ll switch from iOS to Android multiple times a day. Two different IDE’s, two different languages, and two different concepts of what the UI should behave like. It’s not easy to context-switch in this way. Every feature is implemented two different ways between them, too, so I have to solve every problem twice.
Finally, the biggest hurdle trying to work for both platforms at once is keeping up with new libraries. I spent the first 3 months of 2016 on an Android project with a team using newer programming paradigms I’d not yet experienced such as RxJava. When you’re switching between platforms as a developer you’re trying to get your frame of mind right and it depresses your willingness to check out a new way of doing things. Retrofit? Hang on, I barely remember how to use Volley, so I’ll try just maybe that on the next project…k?
Goodbye, Cruel Android
Once I decided I had to pick one platform and stick to it, the only question left was which one.
As it turns out, that decision was an easy one.
In my opinion, over the last couple years, the Android development environment has broken down. Here’s what I’ve seen:
- Google’s adoption of Gradle has been a disaster and proved to me to be a terrible decision. It did help out with some previous deficiencies, namely multiple app targets, but it’s slowed down compilation severely. It also makes for masochistic configuration files with major redundancy and fragmented dependency hosts. Getting an app to compile shouldn’t be a challenge.
- Multidex. My god, Multidex. It’s incomprehensible that Android can’t handle something as simple as keeping track of a few thousand methods, a limit easy to get to as it counts the SDK and your libraries. Multidex kills build times, has led to strange compilation problems, and even needs to be configured differently based on the version of Android you’re running on.
- Fragments are another Android concept that has made life unnecessarily complex for the Android developer. Introduced when tablets came into being, they were better than the classic Activity but have always felt hacked in. This is when Android developers began living off the support libraries. It took years before I used a native Fragment and, even today, I’m not sure that’s even a good idea. I almost wish Android would’ve just redone the concept of Activity/Fragment and started from scratch. Today, some developers stick to using Activities as much as possible while some always use Fragments. You’ll never meet an iOS developer that doesn’t use a view controller, but the most basic of UI concepts in Android make for holy wars.
- Interoperability is another source of unnecessary agony for developers. From the earliest days, the expectation was your application should run activities from other bundles and was expected to share its own with others. As it turns out, very few apps are designed to be used by others…but the architecture still has to handle it. This has led to a difficult environment to pass data between Fragments (using bundles) and special code to handle the simple act of rotating your phone. Passing data around can feel dirty and it takes a lot of effort and care to be sure your activity can be rebuilt from scratch while preserving its state.
- AsyncTask. Years ago Google added this class to the API to “help” developers with background processing. Since then, endless blog posts and discussions have gone into how to use it properly. Google themselves didn’t account for phone rotations, finishing activities, lifecycle changes, and so on. Today, there are endless alternatives to this terribly thought-out helper and it began a trend of many Android tools that were poorly contrived and have led to tons of confusion. (Just look at how many different ways there have been to have a tabbed interface.)
Lastly, the development lifecycle is just so slow. In the beginning, the emulator was nearly unusable. Running an app sometimes didn’t work and you had to spend 2 minutes restarting the thing. Copying the APK takes a while, too. The best way to develop is directly on the hardware, but come on. Genymotion came along and made emulation better for a while, but recently even that became unusable with newer Gradle versions and Instant Run.
And, by the way, did they ever get Instant Run to work right?
So there we go…my days of writing Android code are done. I’m still left with an understanding of how it works and I’ll be able to understand Android code for a long time, but I’m truly excited to go back to being laser focused on the latest and greatest iOS has to offer.
Sorry, Nouget. I never knew ya.