An Android app that I’ve been working on for a few months on freelance basis through Gigster for a client has finally been released. This was the first Android app I have worked on mostly alone and I learned a lot from it.
You can download the app by following the link below
I initially took on this project because I thought it looked like a super simple app and would be a good app to work on to get even more comfortable with Android development. If you look at the design of the app, it’s standard material design that the Google apps follow and didn’t seem to have any complicated parts to it. And in my naive mind, I thought since it followed standard material design, all of the libraries would be provided by the Android SDK and all I would have to do is cobble the libraries together to build the app. I was wrong on that. Thus, onto the first lesson learned.
1. Material Design is just a design concept promoted by Google, not something baked into the Android SDK
Okay, maybe this statement isn’t completely true as the Android SDK does provide some components that are obviously part of the Material Design family. However, there are many components promoted by Material Design that are not the easiest to implement in Android development. Android Chips come to mind for example.
In fact, due to the Android SDK not providing a default way to build out the Chip components, there are various libraries and articles written on how to implement this common component found in Google’s apps. Personally, I think if Google is going to promote Material design in Android apps, they should provide ways to implement all components rather than a select few.
2. Just because Google apps have it, does not mean it’s easy to implement
Google apps like Gmail that follow Material Design to a “T” make it almost seem like building apps with similar features would be easy. But I learned on this project that just because Google promotes something and has it built into their apps does not mean that the feature is easy to implement.
One feature I can think of that Google’s Gmail app has that is difficult to implement is the Account Switcher. In Gmail, you can have multiple Gmail accounts and you can switch between these accounts without having to log out. In fact, it’s such an essential part of the Google Apps’ experience that it almost seems there’s an easy to use API provided by Google to implement this with a few lines of code.
It turned out implementing such a feature put the project’s requirements out of scope due to the extra effort it would require. In fact, this made me curious to see if account switching is a common feature in Android apps built by larger and well known companies like Foursquare, Facebook, Reddit, etc. I could only find one company that implemented this feature and that was Twitter. Needless to say, just because Google does it in their apps does not mean that it’s easy to implement.
3. Documentation in the Android world is not the greatest
I’ve written about this issue multiple times but I found the documentation provided by Google on Android development to be lacking in detail. In fact, some of the code samples would simply not work. This doesn’t just pertain to documentation provided by Google, but it seems to be the case in many of the popular third party libraries.
I come from the Ruby on Rails community and the main difference between the Rails community and the Android community when it comes to documentation is this. In the Rails community, you can learn almost everything you need to about a third party gem via reading the README.md or reading through the Wiki on the Github page of the gem. For third party Android libraries, they provide you a sample app so that you can look through the code. While sample apps provided are useful, I prefer having things thoroughly documented in the README or the Wiki. This way, I can quickly figure out if the library is something I would like to implement in my app or not.
4. Static typing does not mean you don’t have to write tests, especially when building out client side applications backed by a third party API
The whole debate about statically typed vs dynamically typed languages sometimes make it sound like statically typed languages are superior when it comes to writing safe code that doesn’t crash. I have to admit, I do feel way more confident about my code when writing code in statically typed languages like Java compared to dynamically typed languages like Ruby, but I found that this advantage is a bit of an illusion when your application is backed by an API that you’re unfamiliar with and have no control over.
I’m generally used to working in applications where I also have control over the backend systems. Thus, I have clear view of various data integrity rules. When working on Streak, I noticed that I would often run into the dreaded NullPointerExceptions due to me not knowing every data type a column could potentially return. Sometimes the JSON data returned might not have certain attributes, sometimes it would be null, and etc. This forced me to think of every little problems and edge cases that the data returned from an API could present me with and write more defensive code.
5. Working in a resource constrained environment presents different challenges
Generally in web development, you can almost always throw more hardware at performance problems. However, in mobile development, resources are constrained to the devices that the users are holding. Due to this, I found that I had to actually think about writing efficient code that will not use up too much memory, make the garbage collector run unnecessarily, and etc.
In fact, I’ve ran into issues where caching and querying large sets of data caused the app to crash during development. This was entirely due to my lack of experience working in resource constrained environments. Thanks to these experiences, I’ve learned a lot about writing better and more efficient code.
6. Offline apps are not easy
There was a feature in this Streak app that had me cache some data locally. Due to this, the app inevitably had some “unintentional feature” of it kind of having offline features. I’ve noticed this increased the complexity of the app significantly since now I had to manage the state of data locally between different screens rather than simply making a fresh new API call upon loading each screen. Sure, making an API call would be more heavy on battery, but it would make the code simpler and easier to maintain. This experience made me truly appreciate apps with offline features.
I learned a ton working on this app. Working on this app reminded me of working on my first freelance Ruby on Rails app where I learned a lot about writing Rails apps. In fact, I distinctly remember that experience made me extremely comfortable with the Rails framework and I believe that it sped up my learning by at least 6 months. I feel exactly the same about this Android project, especially after I began working on my second freelance Android project where I felt much more comfortable in my technical decisions.