HockeyApp for Android (NDK) [Early Access]

This document is preliminary and subject to change. Support for the Android NDK is live on HockeyApp, and we have more improvements coming soon which will simplify the integration, symbolication, and grouping of crash reports. If you have questions or feedback, please open a support request.

Example Project

You can download an example project is here:

  1. Checkout the code from Github.

  2. Checkout breakpad and put it in a directory with the same root folder. For example: ~/Projects/breakapp and ~/Projects/breakpad.

  3. Switch to the breakpad folder and run ./configure && make.

  4. Switch to the breakapp folder and run ndk-build.

  5. Last but not least, build and run the Java code (I did this in Eclipse, but ant should do as well).

The code is pretty straightforward: The native code initializes breakpad here. The Android files path is set from Java as the API to get it is not available in C++ (or I didn't find it). After a crash, you need to restart the app. Then a Java class is checking for minidump files and uploads them to HockeyApp, see here.

Integrating Breakpad

  1. Follow the steps here to set up Breakpad for your app

  2. Add a JNI method to one of your .cpp files similar to the native.cpp in the example project:

    static google_breakpad::ExceptionHandler* exceptionHandler;
    bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
                      void* context,
                      bool succeeded) {
      printf("Dump path: %s\n", descriptor.path());
      return succeeded;
    }
    
    extern "C" {
    
      void Java_com_hockeyapp_breakapp_MainActivity_setUpBreakpad(JNIEnv* env, jobject obj, jstring filepath) {
        const char *path = env->GetStringUTFChars(filepath, 0);
        google_breakpad::MinidumpDescriptor descriptor(path);
        exceptionHandler = new google_breakpad::ExceptionHandler(descriptor, NULL, DumpCallback, NULL, true, -1);
      }
    
    }
    
    Make sure to adjust the name of the JNI method to your namespace.
    
  3. Copy the code from the file NativeCrashManager.java to your src directory.

  4. In your main activity, adjust your code as follows:

    public class MainActivity extends Activity {
      private native void nativeCrash();  
    
      static {  
        System.loadLibrary("native");  
      }  
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.activity_main);
    
        // Handle NDK crashes
        Constants.loadFromContext(this);
        setUpBreakpad(Constants.FILES_PATH);
        NativeCrashManager.handleDumpFiles(this, HOCKEYAPP_ID);
      }
    
      public void onResume() {
        super.onResume();
    
        // Handle SDK crashes + submit SDK / NDK crashes
        CrashManager.register(this, HOCKEYAPP_ID);
      }
    }
    
  5. Build and run your app.

Symbolication

To get symbolicated crash reports on HockeyApp, you need to upload the symbols for each build. There are two ways to do this:

  1. Dump the symbols using the Breakpad toolchain as described here and create a symbols.zip file with the following structure:

    $ unzip -l symbols.zip 
    Archive:  symbols.zip
      Length     Date   Time    Name
     --------    ----   ----    ----
            0  07-22-13 15:07   symbols/
            0  07-22-13 15:07   symbols/libnative.so/
            0  07-22-13 15:07   symbols/libnative.so/EAC901FB6DDCCE8AED89E1A8E4A58360/
        12468  07-22-13 15:07   symbols/libnative.so/EAC901FB6DDCCE8AED89E1A8E4A58360/libnative.so.sym
            0  07-22-13 15:07   symbols/libnative.so/FDC5C9E715C4F16408C0B78F95855BF0/
        12467  07-22-13 15:07   symbols/libnative.so/FDC5C9E715C4F16408C0B78F95855BF0/libnative.so.sym
     --------                   -------
        24935                   6 files
    

    Drag & drop the symbols.zip to the version page on HockeyApp. Make sure that the filename is named or ends with symbols.zip, otherwise the file will not be accepted.

    If you upload your builds through the API, you can set this file as the param dsym.

  2. Put all .so files from the project folders obj/local/$ABI/ into a .zip file. On HockeyApp, click on your version, then on "History" below "Builds", then on the tab "Symbols". There should be a button "Process .so files". Click it to upload the .zip with your .so files, then HockeyApp will dump the symbols and create the symbols.zip.

    If you upload your builds through the API, you can set this file as the param libs.

Note that the first way only works on Linux machines as the dump_syms tool can not be cross-compiled for Mac or PC. The second way works on all platforms.