Crash Detection in published Android App

Sayantan Banerjee
tech@iiit-gwalior
Published in
6 min readMay 19, 2020

--

In the process of building an Android Application, while testing we face a lot of crashes. We detect a crash, fix it and this cycle repeats until and unless our application is built completely and it’s crash-free. And then, after months of hard work, we finally push our application to the Play Store.

“Tough times over. Now let’s relax and binge series!

. . . But that’s not the case.”

To elaborate the discussion, lets have a conversation between me and my friend:-

Tony Stark:- Hey Sayantan, I am throwing a party tonight at my place. It’s based on my Android Application finally ready for production. You are cordially invited.

Me:- That’s awesome news. Congrats buddy. I will attend it for sure.

Tony Stark:- Thanks :)

Me:- So who’s in charge for maintaining the Application?

Tony Stark:- Maintenance… Umm… No one for now. Well, I don’t need any recent update and it’s completely bug-free as of now.

Me:- Well Tony, that’s not the case. There may be cases when other devices may face CRASH, although your device might be crash-free.

Tony Stark:- Now that’s horrible. How come another device faces Crash?

Me:- Well the primary reason for this is due to different manufacturers present out in the world. Many manufacturers use their own CUSTOM Operating System, customizing different aspects of a device. And these customizations can bring out issues with the application in these devices, thus leading to performance issues and finally CRASH!

Tony Stark:- Never thought like that. Any example where different manufacturers cause problems?

Me:- Background threading requires more handling in Chinese manufactured devices than the Stock Android device, as they tend to stop Services on its own due to Battery Optimisation.

Tony Stark:- Okay that’s a good example. Any other cases where different devices may cause Crash?

Me:- The change of the Android SDK version can also lead to CRASH, as maybe there was a feature that works in the newer SDK version, but not in previous SDK versions and vice versa.

Tony Stark:- Yes, the Application built may not be Backward Compatible. I have taken care of it in various places but don’t know if I have introduced it in all the places.

Me:- Yes Tony. You got my point.

Tony Stark:- So how can we get the crash reports in any device through my Application. Should I go on and check it out in every possible device?

Me:- Well that’s a solution but it’s a bad one. We can use Firebase Crashlytics for gathering all the crash reports and displaying all of them into a user-friendly Dashboard.

Tony Stark:- Wow, seems interesting. Tell me more about it. Is it difficult to handle?

Me:- Actually, It’s one of the easiest things to implement in an Android Application. Let’s discuss it in detail.

FIREBASE CRASHLYTICS DASHBOARD

To solve the above problem, Firebase Crashlytics comes into the picture. Firebase provides a dashboard where we can visualize all the crashes happening to a user using an application.

In the image we can see, we have a Crash-free statistics graph (crash-free users v/s date), Event trends graph (No. of crashes v/s day). Under the Issues domain, we can get the list of all the crashes along with its meta-data like Version of App affected, No. of Events, and No. of Affected Users.

We see a Filter button at the top, where we can further filter the crashes based on Version-number, OS model, and Android SDK. These can be helpful in filtering in the following ways:-

  1. Version-number:- It will help us to understand which sort of users facing this crash.
  2. OS Model:- Many times, some manufacturer’s phones may restrict from performing a certain action, resulting in a crash. We can sort out the data based on this.
  3. Android SDK:- It is really helpful for checking crashes regarding backward compatibility.

Now let’s analyze what we will get when we click on a crash report. For eg, let us click on the first Crash displayed in the above issues section.

  • In this image, we can see a graph analysis of the number of events of crashes that took place, along with the breakdown of the Manufacturer, Operating System, and State of Device in which it happened.
  • At below, we get the Sessions summary containing the whole Stack Trace of the Error. So, developers will get to use this data to trace the error in the code and can fix the error.
  • Apart from the Stack Trace, externally Keys and Logs can be passed to gather more knowledge of the CRASH.

ARCHITECTURAL OVERVIEW

Through this, we can track the crashes happening in various devices. For this, we have to set up the Android Project to Firebase and add the Firebase Crashlytics SDK dependency in the build.gradle(app) file.

Now we can have two types of crashes reports:-

  • The first one is the general crashes, those crashes which stop the application at once. These are tracked automatically by the Crashlytics along with the whole stack trace, device information, affected users, etc and reported to the dashboard. All the graphs and statistics charts are auto-generated at the server-side.
  • The other being non-fatal-crashes, which don’t stop the application, instead throw an error in a try-catch block. We can introduce it at a specific try-catch block of our code, and if the method throws an exception, we can log its Crash report.

IMPLEMENTATION APPROACH

General crashes are tracked automatically, with no additional requirement. For the non-fatal-crashes, we can introduce it inside the Exception block of a try-catch.

try {

// some code which may result into exception

}

catch (exception: Exception) {

Crashlytics.setUserIdentifier(“user_ID”)

Crashlytics.log(“Message_To_Identify_this_TryCatch_Block”)

Crashlytics.logException(exception)

}

Now, these exceptions are not generalized to everyone in nature; i.e can cause trouble to some specific users. So we can receive the user ID by setting a setUserIdentifier. We can log a custom message to identify the appropriate try-catch block. At last, we call the log exception(exception) to log the crash to Crashlytics.

There may be cases in which one of the many ways can throw the exception. So, in this case, we can put keys to further analyze the nature of the exception. We can set String, Int, Float, Double, or Bool values.

Crashlytics.setString(key_name, “value”)

ALGORITHM FIREBASE USE IN CRASHLYTICS

According to the flowchart, we have to just introduce the non-fatal-crash (as fatal crashes will be gathered automatically), and firebase will take care of reporting. So the advantage is, it remains offline until and unless it gets uploaded, for a longer period. Also, firebase uses the best possible way to store the data, so storage is not an issue here. The disadvantage it has to offer is that if a user uninstalls the app after the crash, the crash would not get uploaded.

TESTING APPROACH

After the SDK is plugged in and enabled in the Firebase dashboard, it doesn’t require any additional setup. Firebase Crashlytics start observing for crashes. For testing purposes, we can force a crash to check if everything is working as expected or not.

Crashlytics.getInstance().crash()

We can now attach the above command on a button click, and on pressing the button would crash the App and we can check about its report in the dashboard.

CONCLUSION

So, as we had seen so far, Firebase Crashlytics comes up with a bunch of features for tracking crashes occurring in different devices. It is very easy to implement and so it is recommended to incorporate it into the Android application before publishing it for production. In this way, we get to know about the run time crashes happening at different devices and we have the chance to fix them. Thus with the next release, our application is more bug-free and users would love using it.

Cheers. Happy Developing. Thank you :)

--

--

Sayantan Banerjee
tech@iiit-gwalior

Android Developer | Open Source Enthusiast | Binge watcher | Reader