Making a basic Android app is easy. Making a reliable, scalable, and robust Android app, on the other hand, can be quite challenging.

With thousands of available devices pumped out from tons of different manufacturers, assuming that a single piece of code will work reliably across phones is naive at best.

Segmentation is the greatest tradeoff for having an open platform, and we pay the price in the currency of code maintenance, which continues long after an app has passed the production stage.

Why error reporting matters

So, what happens when an Android app crashes or becomes non-responsive? Well, the “Force Close” dialog pops up, letting the user know that something’s gone wrong. If the app was downloaded through Google Play, the user will be prompted to report the crash by sending a detailed report (including time, phone model, Android version, stack trace, etc.) that you (the developer) can view in the the Developer’s Console, allowing you to address the culprit bug.

This all sound very nice—but there's a major problem with Android's default error reporting: users tend not to use it, leaving developers clueless as to the state of their apps.

This all sound very nice—but there’s a major problem with using Android’s default error reporting: users tend not to take action when their apps crash; in fact, the majority choose not to send in error reports. How, then, can you, as a developer, gain reliable insights into your app’s crashes and failings?

Introducing ACRA

ACRA stands for “Automated Crash Reporting for Android”. It’s a free library that lets you solve the ‘manual error reporting’ problem with a few lines of code. Once you’ve implemented the library and everything has been properly initialized, you’ll be able to extract the same error reports as the Google default (plus a bunch of added customization options) automatically and without requiring the user to take action.

Beyond that, ACRA lets you choose how you’d like to inform the user of a crash, with the default being silent background reporting, and alternatives including customized dialogs.

Until recently, ACRA was backed by Google Spreadsheet, which meant that you were able to receive all your reports in a single file, hosted for free on your Google Drive account. Unfortunately, Google requested that we not use this option in the future, so we’re left with a couple of alternatives for sending in crash report data:

  • Standard email (still requires user interaction).
  • Custom email/HTTP client (requires extensive setup).
  • Custom back-end (with options ranging from free to commercial solutions).

In this article, we’ll analyze one of these solutions: hosting your ACRA reports on a Cloudant back-end and visualizing the data with acralyzer.

Setting up a Cloudant back-end

The first thing we need to do is register a Cloudant account. Of course, there’s a catch: Cloudant’s services are not entirely free, but according to their pricing page it’s very unlikely that you’ll exceed the monthly $5 limit (unless you have huge user base and a ton of bugs in your code).

Once we’ve registered, we need to understand how things work. At a high level, our back-end will consist of two components:

  1. A storage database or, to be more precise, an Apache CouchDB. CouchDB stores its data in JSON format, which means that all reports sent from the Android device must match the format in order to be inserted as an entry. A database insert is a simple HTTP POST or PUT request.
  2. A web app (for analysis) or, to be more precise, a CouchApp. This is a simple JavaScript application that lets you run queries and display the data stored in the CouchDB instance.

In order for our back-end to work properly, we’ll need to setup these two components. In theory, we could build the database and the app from source, and then use a tool to deploy them to our back-end—but the good folk at ACRA have already done that for us. So the easiest approach is to replicate a remote database and a remote app.

Let’s go ahead and replicate an empty ACRA CouchDB:

  • Select the ‘Replication’ section in your Cloudant dashboard.
  • As the source database, select ‘Remote database’ with http://get.acralyzer.com/distrib-acra-storage as the URL.
  • As the target database, select ‘New database’ and name it “acra-{myapp}” (without the quotation marks). Note that the {myapp} parameter should be unique to your app, and that the database name must start with “acra-“.
  • Click ‘Replicate’.

Thus, we have successfully replicated the database for report storing. Next, we need to replicate the acralyzer CouchApp so that we can visualize the data:

  • Select the ‘Replication’ section in your Cloudant dashboard.
  • As the source database, select ‘Remote database’ with http://get.acralyzer.com/distrib-acralyzer as the URL.
  • As the target database, select ‘New database’ and name it “acralyzer”.
  • Click ‘Replicate’.

Note: replicating the acralyzer app is optional. You won’t need it if you’re only interested in storing your crash report, rather than visualizing the data (we’ll take a closer look at acralyzer in the next section). If you feel confident enough with your JavaScript skills, you could even write your own analytics app! But that’s outside the scope of this blog post.

The last step of the initial setup process is to add security permissions. Cloudant provides its own security layer over CouchDB with finer control on individual rights, so in order to write a report to our database we need to create a user account with write permissions:

  • Select the ‘Database’ section in your Cloudant dashboard.
  • Click the permissions section (lock icon) for the acra-{myapp} database.
  • Click ‘Generate API keys’.
  • Write down the generated username and password (we’ll use them later).
  • Add write permissions for the generated username.

Visualizing reports with acralyzer

Once replicated, the acralyzer dashboard can be easily accessed by following https://{myapp}.cloudant.com/acralyzer/_design/acralyzer/index.html#/dashboard. I’ll admit: it’s not the prettiest analytics tool out there, but it serves its purpose.

From the top menu, you can select which database you want to visualize (it is possible to host multiple databases for different apps in a single project; this will affect your usage quota) and preview the data in the main dashboard. For example, you can:

  • Plot the number of reports by unit of time (hour, day, month, etc.).
  • View the distribution of reports by Android-specific metrics (Android version, SDK version, app version, device, etc.).
  • List all reports (with a detailed stack trace) or view all bugs (here, a “bug” is a group of identical reports sourced from different users).
  • Preview details for a single bug and set its status as resolved (if fixed).
  • Purge old or obsolete entries.

Note that the metrics available for visualization will depend on the reports we choose to send from our app. ACRA offers a variety of report fields, some of which can be quite large in size or not completely relevant to bug fixing. For most projects, the required report fields will be sufficient. These include:

  • APP_VERSION_CODE
  • APP_VERSION_NAME
  • ANDROID_VERSION
  • PACKAGE_NAME
  • REPORT_ID
  • BUILD
  • STACK_TRACE

Implementing ACRA in your Android project

As previously mentioned, implementing ACRA is very easy and just requires a few quick steps.

Add dependency

First, we need to include the library as a dependency in one of the following ways:

  • As a .jar file in your /libs folder.
  • As a maven dependency:

    <dependency>
        <groupId>ch.acra</groupId>
        <artifactId>acra</artifactId>
        <version>X.Y.Z</version>
    </dependency>
    
  • As a gradle dependency:

    compile 'ch.acra:acra:X.Y.Z'
    

Add Application class

Next, we need to add an Android Application class to our project (or update an existing class, as there can only be one instance) and declare it in the AndroidManifest.xml:

<application
    android:name=".MyApp"
    android:theme="@style/AppTheme">
    ...

And setup ACRA there:

@ReportsCrashes(
    formUri = "https://{myusername}.cloudant.com/acra-{myapp}/_design/acra-storage/_update/report",
    reportType = HttpSender.Type.JSON,
    httpMethod = HttpSender.Method.POST,
    formUriBasicAuthLogin = "GENERATED_USERNAME_WITH_WRITE_PERMISSIONS",
    formUriBasicAuthPassword = "GENERATED_PASSWORD",
    formKey = "", // This is required for backward compatibility but not used
    customReportContent = {
            ReportField.APP_VERSION_CODE,
            ReportField.APP_VERSION_NAME,
            ReportField.ANDROID_VERSION,
            ReportField.PACKAGE_NAME,
            ReportField.REPORT_ID,
            ReportField.BUILD,
            ReportField.STACK_TRACE
    },
    mode = ReportingInteractionMode.TOAST,
    resToastText = R.string.toast_crash
)

public class MainApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // The following line triggers the initialization of ACRA
        ACRA.init(this);
    }
}

That’s it! Of course, you’ll need to replace all the {myapp} placeholders with actual values, as well as values for formUriBasicAuthLogin and formUriBasicAuthPassword.

As you can see from the above code snippet, we’re only using the required report fields. Feel free to add any other fields that may be relevant to your application.

You can also choose to use PUT instead of POST. In that case, the REPORT_ID will be appended to the end of the former as a parameter.

Finally, you can also choose how the user is informed of the app’s crash, the default being a silent background report. In our case, we choose to display a Toast message letting the user know that the crash has been reported and a bug fix should be available soon.

Need help? Here’s a sample project

To see ACRA in action, I’vs setup the acra_example repo on GitHub. It features a simple app that initializes ACRA on start up and let’s you crash it by pressing a button (which then triggers a null pointer exception). The crash data is sent to an example Cloudant database that can be visualized here.

To view the data, log in with the following credentials:

  • Username: medo
  • Password: acraexample

Alternatives to ACRA

ACRA isn’t the only option for automated error reporting. Since crashes are bound to happen, there’s a big business-to-developer (B2D) market out there attempting to monetize their resolution.

Crittercism, for example, is a very mature platform for error reporting. It looks great, offers a bunch of options for data analysis, and is very easy to integrate. The only downside: price, and the free trial is fairly limited in terms of number of active users, days of data retention, and support). BugSense is a similar service.

In my opinion, however, Crashlytics is a superior solution. Until recently, Crashlytics had a freemium model (with a paid premium tier); but now (after their acquisition by Twitter), all the formerly-premium features are available for free. There are no usage costs, fees, or limits. This is the preferred means of error reporting for a lot of high profile and high ranking companies and developers, as it’s very easy to use and offers powerful analytics and visualization tools. It even integrates with most popular IDEs as a plugin (e.g., Eclipse, Android Studio), so adding Crashlytics to your app is as simple as selecting a project and pressing a button. These plugins also enables you to track crash reports from your IDE without having to open up a browser.

So, why use ACRA then when there are other alternatives out there that look way better and offer more features for the same implementation effort? I’ll give you two reasons.

  1. All these other options are closed source, proprietary software. Even with a basket full of EULAs, you can’t be sure exactly how your data is gathered and handled. On the other hand, ACRA and acralyzer are open source projects hosted on GitHub that you can easily fork and tailor to your needs.

  2. Data mobility. Let’s say you’re unsatisfied with Cloudant. It’s a breeze to replicate and migrate your data to another back-end. You’re guaranteed that the data stays yours.

As with many choices, this one boils down to personal preference and familiarity. Check out this Google+ thread for more discussion on the various alternatives available for making your app more reliable.

In conclusion

ACRA is a highly robust and highly customizable library that can be utilized alongside Cloudant and acralyzer to achieve free, automated crash reporting and basic analytics for your app, all for minimal implementation effort.

Writing reliable Android code requires a lot of experience and foresight, but none of us are truly omniscient. Be prepared for the unexpected, and be ready to fix the unexpected as soon as possible. That’s the kind of work that goes into great products and great user experiences.

Hiring? Meet the Top 10 Android Developers for Hire in October 2014
Like what you're reading?
Get the latest updates first.
Don't miss out.
Get the latest updates first.

Comments

Svetlozar Kostadinov
One correction... formUri = "https://{myapp}.cloudant.com/acra-{myapp}/_design/acra-storage/_update/report" should be: formUri = "https://{myusername}.cloudant.com/acra-{myapp}/_design/acra-storage/_update/report" where myusername is your username for Cloudant account.
Ivan Dimoski
You are right, thanks for the correction :)
Mandar Deshpande
This is a very nice and descriptive article about ACRA, so thanks for this Ivan. I just have 2 minor corrections here. 1) ACRA stands for "Application Crash Reports for Android" 2) android:name you have mentioned in AndroidManifest.xml is "MyApp" and in java files, you have given the class name as "MainApp" for you Application class. This would throw an exception. Both must be same Thanks for the article, keep it up.
Jose Luis Hernandez
Hi, this article helped me a lot, so I was wondering if I could translate to spanish and put it on my blog, giving you the credit of course and putting a link to your article, thanks
Yusuf Rifai
how can i add acra to fragmen,activity or something else?
Anti-interceptare Mobil
At this time Crashlytics registration doesn't work anymore.
comments powered by Disqus
Subscribe
Free email updates
Get the latest content first.
Trending articles
Relevant technologies
Toptal Authors
Software Engineer
Software Engineer
Software Developer
JavaScript Developer
Software Engineer