Category

Android

Android – Wait for two networks requests to finish with Kotlin

In Android, UI operations happen in the main thread while longer running operations such as network requests and database transactions happen in the background thread.

When building mobile apps against public APIs, there are times where you have to make a network request to multiple endpoints in a single screen, but only display the entire screen once all of the network requests have completed. As mentioned at the beginning of this post, network requests are done in a separate thread, which is usually managed by whatever networking libraries you are using (it’s probably Retrofit), RxJava, or if you’re doing it manually in an AsyncTask.

Threads are hard. I don’t like threads. I have a difficult time understanding it, working with it, and managing it. Slight mismanagement of it can lead to all kinds of issues like race condition where it can become annoying enough to debug where you’ll want to flip a table. As mentioned above, when you have to build an a screen in a mobile app where you have to make a network request to more than one endpoint at a time, and only commence an operation (like displaying data on a screen) once all of the network requests have finished, you’ll have to figure out how to listen for when different requests, essentially threads, have finished loading.

There are multiple ways of going about this in Android. Some people will say look into CountDownLatch while some people will say to learn RxJava. While both suggestions will work, CountDownLatch looks too complicated for me to bother understanding and RxJava has too high of a learning curve for it to be a viable option if you need to learn how to do this quickly. If you use Kotlin, you can also look into coroutines but that’s apparently an experimental feature according to JetBrains.

While trying to figure out how to do this I found a Kotlin library called Kovenant that makes asynchronous operations super easy on Kotlin. If you’re unfamiliar with promises and asynchronous calls, the TLDR is that you run some code asynchronously and promises allow you to commence the next sequence of operation once that initial asynchronous operation has finished running. Kovenant also makes it easy to combine multiple promises, which is what we’ll be using to wait until two network operations are finished before commencing our UI operations. Let’s look at some code sample from the redesign I’m working on for MaterialReads.

In this redesign, I need to have data from two different endpoints: updates and reviews. Unfortunately, GoodReads do not provide an endpoint that reads both datasets in one API call, thus I have to make two. I want to be able to display a loading spinner while data from both endpoints are being loaded and then hide the loading spinner only if the two network requests have finished running its full course. This would be difficult to do manually but Kovenant makes it easy. As displayed in the code sample, we split the both network requests into two separate methods, and then create a deferred object. We only resolve the deferred object if the request has been successful in each network request.

In our refresh method, we can combine the two promises, which will allow us to wait until two network requests have finished loading and load the updates and reviews that have been retrieved from the API. In this example, we’re only combining two promises, but Kovenant allows you to combine up to 20 promises at a time.

If you Google how to wait and detect if multiple asynchronous operations have finished, you’ll get slews of answers that range from very manual (which also can mean error prone) to something like “just learn RxJava and reactive programming”. I found that the using something like Kovenant and its easy to use promises is the best way to solve this problem of asynchronous callbacks.

Goodreads OAuth in Android

For my solo project, I’m building a Goodraeds client. Mostly because I like to use Goodreads to track the books I’m reading and I don’t enjoy the default Android app provided by Goodreads.

Thus, I’m building my own alternative using their API. However, it has been a tricky process from the beginning since

  1. Goodreads API isn’t very well documented.
  2. Logging in via Goodreads means that I need to do OAuth authentication with their API, which as mentioned in point 1, is not very well documented, and also is OAuth 1.0.

It took me some time to figure out how to perform OAuth authentication in Android development and I’ll go over the steps on how to do this in the hopes that it’ll save other people a bunch of time.

Just as a note, since this is Android development, the code samples that I’ll be showing will work in any standard Java application or any language that can easily interpolate with Java and targets the JVM. Also, since I’m writing this app in Kotlin, do note that the code samples will be in Kotlin with the exception of one small portion that relies on a library. But if you need to use Java, you can always look at the code sample and figure out what’s going on pretty easily.

Things that we will need

We’ll need several components that come together to make OAuth authentication work. They are:

  • Goodreads developer key and secrets
  • Your own server that will act as a callback url for the Goodreads OAuth API
  • ScribeJava library for making OAuth easy

As far as setting up your own server that will act as a callback url for the Goodreads OAuth API, you’re on your own. What you’ll have to do is set up a simple API that will receive the callback url that includes the OAuth token and whether the user authenticated your app from accessing his/her data or not from Goodreads API with a route that you’ll set in the Goodreads API Developer dashboard.

1 – Register for the Goodreads developer keys

Just Google something like Goodreads API developer keys and you’ll find a link in Goodreads that will allow you to register for the developer keys so that you can access their APIs. Once you have registered yourself as a developer, you’ll be redirected to a page that looks like this that will provide you with your developer key, secret, and form with inputs where you can enter in your app’s name, domain, and a callback url. Fill these out appropriately with the exception of the callback url.

2 – Set up your own API to act as a callback url

I won’t go into the details of how to set up your own API to act as a callback url. It shouldn’t be too difficult if you’re somewhat familiar with backend development. All this server has to do is take in two parameters, oauth_token and authorize which will be coming from the Goodreads API to your callback server, and then render the results in a json format. I like to user Ruby on Rails for backend development purposes and for the sake of providing a simple example, this is what my controller looks like.

And my routes file looks like

Having my Rails controllers and routes like this will give me a url that goes something like https://myurl.com/goodreads_oauth_callback.

Once you have deployed your server, go back to the Goodreads page where your developer keys are listed, and fill out the Callback URL form. Just as an example, mine looks like this (sensitive data blurred out).

3 – Install ScribeJava

Depending on what you’re developing, you can do this several ways. In the context of Android development specifically, simply add this line in your app’s build.gradle file.

Notice here that I’m using an older version of ScribeJava. As of this writing, the latest version of ScribeJava is at 5.3.0. For whatever reason, I couldn’t get Goodreads OAuth to work with the latest version of ScribeJava as I kept running into an exception that I couldn’t find a solution to. Thus, rather than trying to figure out how to make the latest version of ScribeJava work, I decided to simply use a version that worked out of the box. If you want to try to get the latest version of ScribeJava to work, give it a try. If you want the easy way and get Goodreads OAuth authentication to work following my code samples, stick with version 4.2.0.

4 – Set up a Goodreads API adapter for ScribeJava

ScribeJava comes with a lot of different adapters to help make it easier for the user to work with various popular OAuth authentication services like Twitter, Facebook, and etc. However, it does not come with an adapter for Goodreads. Thus, we’ll have to write one. Don’t worry, it’s fairly simple. We’ll write this one in Java instead of Kotlin. Also, since Kotlin interpolates with Java, feel free to write this one in Kotlin if you desire.

5 – Authenticate the user via OAuth

This is the part where we’ll put everything together so that users can use Goodreads OAuth to authenticate with your app. One thing about the Goodreads OAuth is that user authentication happens via their login page. Thus, whatever you’re building, you’ll have to redirect your users to a webview of some sort to display the login form provided by Goodreads. The code sample below is for Android development, thus we’ll be using the standard Android WebView. If you’re not doing Android development, adjust your code accordingly.

While the above code should be relatively easy to follow and understand, I’ll explain the most important part where we retrieve the authenticated user’s access tokens and secrets that we’ll be using to make requests to the Goodreads API.

You’ll see that I override onPageFinished method in my GoodreadsAuthView webview. In this overridden method, I check to see if the url in the WebView contains the callback url that we defined in the Goodreads developer page. If it does, we will grab the query parameters in that url to retrieve the oauth token and whether the user has authorized your app to access his/her data. If the user has authorized your app to access his/her Goodreads data, the query parameter authorize will return a String value of 1.

From here, we check to see if the query parameter authorize has returned 1, and then retrieve the access token and the access token secret utilizing the ScribeJava library. We then use these tokens and the ScribeJava library to make special OAuth request to the https://www.goodreads.com/api/auth_user endpoint so that we can parse out the authenticated user’s user_id. The /api/auth_user endpoint is a regular endpoint defined in the Goodreads API documentation, but for whatever reason, I found it close to impossible to try to retrieve this with regular curl requests (or using Retrofit in Android). However, if I use ScribeJava’s built in functions, retrieving the user_id of the authenticated user is very simple. To be transparent, this part where we try to retrieve the user_id of the authenticated users is the part where most developers seemed to be having trouble based on the questions posted in the Goodreads developer forums. ScribeJava makes this process simple as one line of code.

Note that once we sign the request using the access token and ScribeJava’s built in functionality, we need to parse out the user_id from the XML that gets returned from the Goodreads API. Once we have retrieved the user_id, we can go ahead and save the user_id, access_token, access_token_secret, and then oauth_token in a SharedPreferences so that we can use them throughout the rest of the codebase.

Conclusion

This actually took me around 2 days to figure out how to do. Yes, it seems long to figure out how to do a simple OAuth authentication, but it’s a lot more difficult than it should be due to the lack of support and documentation from Goodreads. I’m hoping that this blog post helps anyone who’s trying to work with the Goodreads API. If you have any questions, feel free to leave a comment below or email me directly. Thanks for reading.

Navigating with BottomNavigationViews

You know those BottomNavigationView’s that are more commonplace in Android apps these days?

Recently, I’ve been building a small sample app for a PluralSight course I’m working on that has one of these BottomNavigationView’s and it wasn’t apparently obvious to me how I should be switching the actual views that are on screen as the user taps through various items in the bottom menu. A simple Google search didn’t answer my question either since most blog posts and StackOverflow answers on the subject matter did one of the following:

  1. Simply introduced the BottomNavigationView and left it at that
  2. Switched the views using a ViewPager but when I downloaded the sample app, the effect seemed a bit weird
  3. Recommended starting up an entire Activity every time a user tapped on a new menu item, but I didn’t like that since that meant you had to re-inflate the bottom navigation view every time. Also, when I implemented it that way, there seemed to be a bit of a lag every time I tapped on a new item.

Thus, I decided to implement the switching of BottomNavigationView menu items by inflating appropriate Fragments into the view. And now… let’s go over the code on how to implement this 🙂

First, our XML layout

And our content_main.xml file

And the bottom_navigation_menu file

These two layout files and the menu item xml file will give us a screen that looks something like this.

Now, what we want to implement is the actual switching of the screen in display. The screen in-display is actually the fragment that is inflated from the MainActivity. Also, when the user taps on a bottom menu item, we want the appropriate fragment to take place of the previous fragment. Here’s how we do it.

In the code, you can see that I inflate a new HomeFragment, which is the default fragment in my code sample automatically, which I store into a mCurrentFragment variable. And based on what the user taps on the BottomNavigationView (which I have a listener set on), I store the appropriate newly instantiated fragment to the mCurrentFragment variable and display that fragment instead.

So far, this is the simplest and most modular way I could think of to get this working. Google docs didn’t seem to have recommended approaches, and blog posts online didn’t have solutions that I liked. The solution that seemed to give the most fluidity that didn’t use fragments like I do involved simply hiding and then displaying certain elements in the layout file depending on which menu item was active. I didn’t like this since that meant unnecessary code will have to be run all at once, potentially causing memory problems.

Dependency Injection with Dagger 1

Note: This blog post will be more geared towards Dagger within the context of Android development. I think the terms that software developers use to describe certain concepts makes simple things seem way more difficult than it is.

Dependency injection is one of them. When I first heard of the term a few years ago, my brain went, “Hmm, that sounds like a concept that will take me years to fully understand”. But nope, all it really means is you pass in instances of other objects/classes in the initialization block of a class.

In Java land, it might look something like this.

In Ruby land, probably something like this

Yes, I realize these are probably not the most extensive examples, but I hope that the readers will get the point. All dependency injection really is involves passing in instances of other objects into the target class that the target class may need to do stuff.

Enter Dagger

If you do Android development at all, you’ve probably heard of a library called Dagger. Dagger is a dependency injection framework that helps you manage dependencies in your Java applications. At the time of this writing, there are two versions of Dagger: Dagger 1 and Dagger 2. Dagger 1 was written by the fine folks are Square and Dagger 2 was written in collaboration between Square and Google, and is currently maintained by Google.

Dagger 1 vs Dagger 2 are kind of like Angular 1 vs Angular 2 (in a way…). Both Dagger 1 and Dagger 2 are dependency injection frameworks that aim to solve the problem of managing dependencies throughout your codebase. Both are independent of the Android framework and can be used in any Java application.

Dependency injection looks relatively simple, in the above code sample with the Knife class being injected into the Kitchen class. So if it looks simple, why do we need a dependency injection framework?

In real life application codebases, specifically in Android codebases in my case (since my experience working with Java is limited to Android), I found myself passing injecting dependencies in almost all of my utility classes that I’ve written to help encapsulate certain functionality. For example, one thing that I generally do in my Android applications that’s backed by an API is store user tokens in SharedPreferences. I generally end up writing a class called TokenUtil that takes in a Context as a dependency since you need a Context in order to be able to utilize SharedPreferences. So something like this.

And in my Activity classes, I always end up having to initialize my TokenUtil with the Context. For example:

This seems relatively innocent and simple, but then again, this is a simple example. I’ve seen classes that take a large amount of dependencies in order to function. And in large codebases, it becomes complicated to manage these dependencies just to utilize different classes throughout the codebase. Dagger helps to manage this chaos.

So why write a post about Dagger 1 instead of Dagger 2?

To be honest, I don’t know. I was chatting with PluralSight about authoring a course on Dagger, and they suggested that we start with Dagger 1. The reasoning was that there are still probably large amounts of codebases on Dagger 1 that have not upgraded to Dagger 2, so that there are probably many professional Android developers who still have to work with the older version of Dagger.

With that said however, if you’re starting a greenfield project, it makes no sense to go with Dagger 1 as it is no longer maintained. Just go with Dagger 2. If you’re in a situation where you still have to work with Dagger 1 however, read on.

How to use Dagger 1 within Android

As mentioned above at the beginning, this blog post will be more geared towards Dagger 1 within the context of Android development. Dagger is said to have a high learning curve. I found this to be…. not really the case. Yes, if you want to learn every little parts of Dagger, perhaps. But to start using it to reap the benefits of using a dependency injection framework, you can get started within about an hour or so. I’ll go over how to set Dagger 1 within the context of an Android application.

1. Add Dagger to your app’s build.gradle file

At the time of this writing, I believe that version 1.2.5 is the latest for Dagger 1. And since Dagger 1 is no longer maintained, it will likely be the last version released for Dagger 1.

2. Create an Application class that extends from Application

Create an Application class that extends from Application class, and set it as the app’s Application in AndroidManifest. So if your app’s name is PocketLifts (name of a side project I’m working on), you might name the class like this.

And in your AndroidManifest, set the PocketLiftsApplication as the app’s main Application class.

3. Create your Dagger modules to define your dependencies

This is where I’ll have to pause a bit and explain something called the Object Graph. Remember how the TokenUtil class required a Context class? In this case, TokenUtil has a dependency on the Context class. What if you have an object that has multiple dependencies? And what if some of those dependencies have other dependencies? You can imagine that you could draw a graph of some sort with different dependencies linking to each other via a line. Dagger draws and manages this graph for you. But in order for Dagger to be able to draw and manage this graph, you need to tell Dagger about the dependencies you want Dagger to manage in your application. We define these dependencies in Dagger modules. Let’s first write a module that will define the godfather of all dependencies in Android development, the Context class. We’ll create a class called AndroidModule where we’ll define all classes/dependencies that comes from the Android SDK.

The @ForApplication annotation is a custom annotation that ensures that the context provided by Dagger can be distinguished from the main application’s context. To define the @ForApplication annotation, create an interface that looks like this.

In the AndroidModule, the @Provides annotation marks that the provideApplicationContext method will make sure that Dagger will “provide” a Context when needed and the @Singleton annotation ensures that the Context will be a singleton.

Next, let’s create a module called PocketLiftsModule where we’ll define our custom dependencies specific to our application. In this PocketLiftsModule, we’ll have it provide the TokenUtil class mentioned above that takes in a Context as a dependency.

In here, the @Module annotation takes in a few parameters. The complete = false annotation signifies that the module is allowed to have missing dependencies. This complete variable is set to true as default, but here we’re setting it as false so that our code compiles. The more important parameter that we pass in is the injects parameter where we define the classes in the codebase where we’ll be injecting the dependencies that are defined in the module. In our case, I want to be using Dagger to inject and utilize TokenUtil in the LoginActivity class and the MainActivity class. The provideTokenUtil method takes in a Context as a parameter and it returns a new TokenUtil that’s initialized with the context.

4. Inject your modules in the Object Graph in PocketLiftsApplication

With our Dagger modules defined, let’s go back to our PocketLiftsApplication to inject our modules into the object graph so that Dagger knows what dependencies we have in our application.

Here, we set the Dagger modules that we have just created and create the ObjectGraph by setting the modules as dependencies. Then we create a new method called inject on our Application class that calls the inject method on Dagger’s object graph.

5. Create a BaseActivity class that initializes Dagger

We’ll have to create a BaseActivity class that extends from AppCompatActivity, and then initialize Dagger by overriding the onCreate class. Then we’ll have MainActivity and LoginActivity extend themselves from BaseActivity so that Dagger can be used to inject dependencies in those two classes.

6. Inject the TokenUtil dependency in LoginActivity (or MainActivity)

Dagger is all set up and ready to be used. All you have to do to initialize TokenUtil using Dagger is define the instance of a class using the @Inject annotation.

And… that’s pretty much it for setting up and using Dagger as a dependency injection framework.

So what is this object graph thing?

Remember how I mentioned Dagger’s object graph a few times throughout this blog post and how we set it up in our PocketLiftsApplication class? The way Dagger manages dependencies is by building a “graph” of dependencies in the methods marked with the @Provides annotation.

For example, our provideTokenUtil method takes in a Context as a dependency. Dagger sees that the TokenUtil requires a Context as a dependency, so it looks through the different modules that you set for the object graph to find a context. In our case, it’ll see that there are no Context in the PocketLiftsModule class, thus it’ll look in the AndroidModule class to find the Context class. It’ll then take that Context to inject and initialize the TokenUtil class and then provide a fully initialized TokenUtil class where it’s initialized it via the @Inject annotation.

Conclusion

This is just a quick overview of how to set up and use Dagger. There are definitely more configurations that you can make to use Dagger, but this guide should get you quickly set up and running.

ButterKnife or not

In one of the freelance networks where I work on Android apps, there have been an effort to standardize the code review to come to a mutual consensus on how every Android developer should write their code.

The effort was made to standardize coding practices because code quality is a subjective thing. And at this freelance network, there are code reviews done with scores given to determine whether the codebase is healthy enough for the team to move onto the next phase of the project or not. And since code quality is very subjective, there have been issues where certain codebases would get a wide range of scores, from downright terrible to excellent.

For Android development specifically, it was decided that libraries like Android’s own databinding or the popular ButterKnife had to be used to reduce boilerplate when it comes to assigning XML elements to variables was something that was required for every Android apps written. Specifically, I’m talking about removing the findViewById calls. For example…

The above is a vanilla Android example, where we declare a mButton variable of type Button, and then use the findViewById call to assign a button that’s laid out in the XML to the mButton variable. Let’s compare this to ButterKnife.

Now, I understand that beauty is in the eyes of the beholder, but I am still confused on why the Android community thinks that the ButterKnife example is less boilerplate and looks cleaner. All ButterKnife seems to do is shove all the bindings to the top of the Activity class. I guess the ExampleActivity has one less line of code (and that lines of code will start adding up), but the amount of reasoning I have to make in my head is more or less the same as the vanilla Android example.

I agree with the general consensus that reducing boilerplate is a good thing. But to me, reducing boilerplate means that things are abstracted to a point where I’m not even aware that the extra code exists somewhere. All what ButterKnife and DataBinding seem to do is simply shove the bindings away to some other parts of the codebase. And to me, that’s not reducing boilerplate. It’s just moving code to somewhere else.

Streak for Android released

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

https://play.google.com/store/apps/details?id=com.mobile.streak

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.

Lessons 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.

Conclusion

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.

Standardizing Android development

When I first started working with Android development, I was confused to no end.

I wasn’t confused not necessarily due to the Android framework, writing Java, and whatnot, but mostly due to lack of documentation on the standard practices when it comes to building Android apps. This might have a little bit to do with the fact that I was coming from the Ruby on Rails ecosystem, where the “convention over configuration” paradigm reigns supreme.

For example, in Ruby on Rails, if I want to query the database, there’s ActiveRecord that comes with the framework. If I wanted to send mails, there’s ActionMailer. If I want to run background jobs, there’s ActiveJob. If I want to <insert whatever a typical web application should do here>, there’s… you get my point. The thing is, Ruby on Rails came with standard ways of implementing the majority of what your typical web application should be able to do out of the box.

In Android, there was no such ecosystem built into the framework. The course I took on Android development had the students manually making HTTP requests to request data from the API, writing raw SQL queries to cache and query the local SQLite database, and so forth. However, as we all know that in the real world, no one develops applications this way. Rather than writing raw queries, we use ORMs to make our lives easier. And rather than coming up with our own ways to manage network requests, we tend to use libraries to set up our API calls simple to make.

In an ideal world (or at least in my ideal world), all these features would be baked into the Android framework. Anyone new to Android development will have the ORM, API mapping libraries, and other components needed to build apps out of the box. Instead, what we have to do today is utilize third party libraries to fill in the holes that the Android SDK doesn’t.

Third party libraries are great. I believe that having a plethora of third party open source libraries is part of what makes a great community. Ruby on Rails for example has open source gems written by individual contributors (or companies) for just about anything you can think of. This is not to say that Android doesn’t either, but the problem in the Android world is that because a lot of these functionality has to be provided via third party libraries instead of by Google, lots of new developers have to spend time picking which libraries they should use.

For example, what do you use if you need an ORM? Do you go with GreenDAO, SugarORM, or Realm? If you need an easy way to display images, do you use Glide, Picasso, or some other library? Thankfully, some of these choices become obvious quickly because the Android community have decided on which libraries to use in most projects. For example, Retrofit is the default go-to for setting up API calls. However, for types of libraries like ORMs, the choice isn’t as clear.

This problem isn’t just unique to the lack of default libraries provided by Google. It applies even in how Android apps are structured. In many full stack web application frameworks, when you start a new project, you’re given a default folder structure for where to put your models, controllers, views, and etc. In Android development, you get nothing. Literally nothing, with the exception of your assets. Every Android project that I’ve worked on had different folder structures, and it always took me some time to adjust to the codebase’s organization and become productive. Contrast this to something like Ruby on Rails, where it’s reasonable for a new developer to start committing new code within the first hour or two of project setup thanks to its convention over configuration paradigm.

When it comes to the folder organization/structure of the codebase, the Android community have tried to alleviate this problem via promoting certain architectural patterns like MVP (Model-View-Presenter). The problem with this is that everyone has a slight different way of implementing these patterns, thus leading to further fragmentation.

Some people might say that this is a good thing. That developers are given the freedom to pick and choose what libraries they want to use and how to go about structuring their codebase. While this argument has some merit, I have to disagree in that it unnecessarily raises the barrier to entry for new aspiring Android developers. Frankly, I think it also decreases overall productivity for the entire Android community. Every time I jump into a new codebase and I see some new library or architectural pattern, folder structure, and etc that I’m not familiar with, I go, “Ugh, now I have to spend time and mental energy figuring out this developer’s brain thought process rather than solving the actual problem on hand”.

One could argue that the amount of mental energy needed to absorb how a new codebase is structured or even choosing which library to use is miniscule. Perhaps they are insignificant individually, especially for simple things like choosing a library to display circular images, but all these are decisions that you have to make. And the energy spent making these tiny decisions eventually add up over time. This is mental energy that could have spent actually building the app or fixing bugs.

There have been recent efforts by the Android team to standardize this by releasing Android components. There have been many blog posts about Android components like Room, LiveData, and etc. In fact, I was listening to an episode of the Android Developers Backstage podcast (episode link http://pca.st/K7uy) and the hosts talk about this exact problem where there’s a lack of standardization and conventions in the Android development world and Android components is the Android team’s effort and addressing this very issue.

These component libraries by Google are still in their early stages and I believe that it’ll take some time for a lot of older Android apps to start integrating these into their codebase. As for me, I’m excited by the notion that one day, I’ll never have to think about problems that aren’t directly related to domain problem of the app that I’m working on. Just think about it. Being able to jump into a project and immediately knowing where everything is based on the community’s conventions and being productive right away. Sounds great to me.

Obfuscate builds before releasing apps

Obfuscating builds is one of those things that I didn’t pay attention to (and wasn’t even aware of) when I first started learning how to develop Android apps. I thought all I had to do was upload a release build of my app to the Google Play Developer Console and I was done.

Obfuscating builds is a straightforward process, but there are a few things that I learned during my client projects that weren’t obvious to me.

Obfuscate your app early in development cycle

Most of my client work involves regularly releasing builds incrementally as an alpha release to the Google Play Store. Some people say that you can obfuscate your builds before you release to production, but it’s better if you do this early in the development cycle.

This is because it can be difficult to figure out what didn’t obfuscate properly later in the development cycle when the codebase is larger. Doing this early allows you to catch any issues with obfuscation when the codebase is smaller and incrementally as the codebase grows.

Obfuscating builds is really easy. Just set minifyEnabled to true and map your proguard files with appropriate rules.

Configuring proguard rules is another subject so I’ll skip that in this blog post.

Upload your mapping files along with your obfuscated builds

When you upload your apk to the Google Play Developer Console, upload your mapping file after you release your build. Also, if you’re using something like Firebase Crash Reporting, you should also upload your mapping file there as well. This will allow you to see where in the code the app crashed if it does happen.

The mapping file can be found at app/build/outputs/mapping/{build_name}/mapping.txt.

Set SerializedName to your POJO attributes

If your app is backed by an API and you’re using Gson (default by Retrofit, which you’re probably using) to map your API JSON responses to your POJOs, you want to define @SerializedName in your class.

Something like the above will suffice. The reason for this is when you turn on obfuscation, those field names will be renamed to something like “a”, and then Gson’s Java to Json mapping will fail. Thus, you need to provide @SerializedName on every field you use for Json serialization with the name of the Json property which needs to map to your POJOs.

Returning to the parent activity

I recently had to resolve a bug in one of my projects where if the user pressed the back button in the Toolbar to go back to the previous screen, the app would crash.

And the app would crash because the previous screen was supposed to be displaying a data that was passed from the screen before that, and the activity would for some reason lose reference to the variable that was supposed to represent that data. To illustrate what I was experiencing, the flow went something like this.

Screen A -> Screen B -> Screen C

Let’s say the app is a cupcake ordering app. Screen A displays a list of cupcakes. User clicks on one cupcake and we display the single cupcake in Screen B. User clicks “Order Cupcake” which takes the user to Screen C. The user decides he/she does not want the cupcake and presses the back icon in the Toolbar.

Note: the bug does not occur if the user presses the Android’s native back button, the one on the bottom of the phone that’s native to the OS.

Once the user clicks the back icon in the Toolbar, the variable that represents the cupcake in Screen B will become null and it would cause the dreaded NullPointerException.

Clicking that in Screen C would crash the app in Screen B with the NullPointerException

And the code in Screen B looked something like this.

And in that code, mCupcake would become null and cause all sorts of NullPointerExceptions.

Now, why was this happening? It turns out that it’s due to the way I declared my activities in my AndroidManifest. In my AndroidManifest, I had declared my three activities like this.

It looks “correct” but it turns out the reason I was having the crashes with NullPointerException‘s was due to missing the android:launchMode="singleTop" in each of the activity declaration.

For example, each declaration should have looked like

Why is the launchMode option so important? It turns out that the standard launchMode (meaning if you don’t put one in), causes Android to always recreates the activity (calling onCreate) even if the task stack (parentActivityName declaration) is handled correctly. To prevent this, you need to add the launchMode="singleTop" declaration to your activities.

The link to the documentation is

https://developer.android.com/guide/topics/manifest/activity-element.html#lmode

For some reason, I think the default configuration should be to have the launchMode set to singleTop when the user presses back into the previous activity, rather than recreating the activity entirely. I can’t think of a single app that I use where I expect pressing the back button on the Toolbar to behave differently than when I press the Android OS’s back button.

Keep your Android Monitor logs when app crashes

My apps crash all the time during development (thanks to plethora of those pesky NullPointerExceptions).

Okay, probably not the best way to market myself BUT I do fix those bugs before the build is released to production (or alpha, or beta, whatever stage the app is currently in development). One thing I wanted to cover in this post is a neat little trick that I learned recently on how to keep crash logs during development.

Most of the time, when apps crash while running in Android Studio, you can see those little red error messages in the Android Monitor.

These logs tell you exactly what happened and where so that you can go and fix it. Pretty easy right?

But this is only applicable if you app is in a crashed state. If your app restarts automatically thanks to the Android OS trying to save face, these logs will be reset and your error messages will be gone, leaving you unable to figure out what went wrong in your codebase.

The way I used to figure out where my app went wrong was like playing a stealth video game like the old Metal Gear Solid games on the original PlayStation where you had to sneak up on your enemies to kill them. I would literally have my screenshot tool ready, open the app in my physical device with the Android Monitor open to full screen, replicate the steps necessary to crash the app, and as soon as the app crashed, try to time my screenshot so that I can capture the error messages before Android Studio erases them from my view. Yes, super primitive and a silly way to go about it.

I can’t remember why (I read it somewhere awhile ago)… but apparently the reason Android Studio wipes the logs when the app restarts is actually a feature that’s supposed to make your development life easier. But if you’re in a situation where you want to keep your logs for whatever reason (i.e. being able to see your error logs), you can create a custom filter configuration in your Android Monitor that won’t erase your previous logs even if your app restarts.

In the top right section of your Android Monitor, click the dropdown and create a new Logcat Filter.

Name your Filter whatever you want, and simply select that filter when trying to replicate the crash. You’ll see that your logs won’t be erased even when the app doesn’t restart.