Learning any new technology takes time and practice, but for Android you may be developing for 2-3 years and still struggle with it every once in a while. During the past years, I’ve worked on a few medium-sized Android projects for clients and almost for each of them I’ve had similar problems occurring over and over again. Why Android development is hard? Below is a list of problems that me and (possibly) many other developers have when developing Android apps:
Supporting very different devices
At the very least, you are going to support 4 inch mobiles to 10 inch tablets running different android versions. This means you’ll want your UI to look good and optimized for these different screen sizes. You would also need to care about screen densities. Eventually all of these means coming up with at least 2 sets of UI designs and 3-4 sets of resources for different screen densities. This also doubles the testing effort.
Configuration Changes = You are fucked
One of the most annoying things every developer has to deal with is the configuration changes. Rotating the device is a common configuration change where your Activity/Fragment is destroyed and recreated. While there is some persistence of data and some views retain their history, you will have to save and restore your shit by yourself. This is not a big deal until you start using things like AsyncTasks and get context leaks, sudden crashes and mysterious bugs because your asynctask and your newly created activity are no longer “on the same page”. To fix this problem, you can either disable screen orientation changes which users hate or use an invisible fragment containing your async/thread etc. that retains its instance after screen orientation changes. Sure, this fixes the problem but why do we have to deal with it in the first place? It just adds to the complexity of your development for no good cause.
Chunks of Boilerplate everywhere
Initially, most of the code you write is pure boilerplate. setting up the views, their elements, their listeners etc. This soon leads to messy code that you must scan in order to find the interesting stuff. Libraries like Butterknife may help reduce the visible boilerplate in the source code at the cost of potential maintenance overhead.
Defensive Coding or Crashes
Null checks everywhere! Even when you think there’s no way something is null, it happens to be null on your user’s device.
Almost every method you call and every object you create takes a Context parameter. You are forced to pass around context references between objects and their methods. Holding on to context references can avoid the garbage collector to clean up the destroyed activities from memory, and soon you run out of memory. Using an invalid context can cause runtime exceptions as well. The solution is to make sure you release context references once you are done using them.
Development Tools and Build Systems
In the beginning Eclipse was the choice of IDE, then came Android Studio. in Eclipse we used Ant to build the app, in AS we use gradle. This change of build system meant if you wanted to use Android Studio or intellij idea, then you would have to learn yet another tool to build apps. I would be okay with that, but Android Studio is a “Preview” version which has lots of bugs. Almost every update breaks something, even updating Android Build Tools can mess up your project. This also leads to problems when working in a team where some people prefer eclipse and the traditional way of building apps. There’s a export tool that helps you migrate eclipse-based android projects to Android Studio but it doesn’t work properly when you have 3rd party libraries (for example actionbar sherlock). Other than Ant and Gradle, we have Maven as well which is used in many projects. These all add to the complexity.
Unit/Integration/UI tests are just messy
Android is not test friendly at all. Wanna write tests for your app and make sure you don’t break things along the way? You thought jUnit and a mocking library is enough? Nope, learn how to use libraries like robolectric, robotium, fest-android and espresso. Figure out how to get them work together and then how to integrate these tests with your Gradle build system. yet more tools to learn and more maintenance.
Libraries and Dependencies
In any not-so-simple app, a bunch of libraries are used either to support earlier versions of android or to make use of extended features. For me, a typical project uses 3-10 different libraries. This causes a huge maintenance problem in the long run and stability issues because 3rd-party libraries often have bugs that crashes your app in some circumstances.
Works on one device, crashes on the other
This is very common, some manufacturers ship their devices with heavily modified Android OS. Some libraries might have changed or not exist at all. Some callbacks may not occur and some special hidden “features” may break your app. Solution? just hope that you can figure out how to fix the bug without making the app crash on other devices.
Simply put, Android versions used to be a pain in the ass; Fortunately, this nightmare is almost over as more and more devices are running Android 4.x. Having to support versions 2.2+ meant you would need to use Google’s support library and other third party libraries such as Action Bar Sherlock just to have a basic consistency in different versions. You would also need to test the app on both an old phone and a new phone to make sure you are actually getting the same result on both. Also some features of 4.x are not available in support libraries.
Overall, developing simple and low quality apps for Android might be easy but good apps are difficult to build individually and are more difficult to maintain. Sadly in the end it might not even worth it financially.