Android Native Development Kit (NDK)

The Android Native Development Kit (NDK) allows you to implement parts of your app in native code, using languages such as C and C++.

NDK integration is packed with the SDK and requires API level 16. The package sentry-android-ndk works by bundling Sentry's native SDK, sentry-native. As a result, even if a native library in your app causes the crash, Sentry is able to capture it.

You can disable the NDK integration, use our Sentry Android SDK without the NDK, and support devices on API levels lower than 16.

Symbolicate Stack Traces

To symbolicate the stack trace from native code, we need to have access to the debug symbols of your application.

Use the Sentry Android Gradle Plugin to upload the debug symbols and sources automatically.

Alternatively, in case you're not using Gradle, you can upload your .so files manually via sentry-cli. Please check the full documentation on uploading files to learn more about the upload of the debug symbols.

To use the Android NDK in your native code, include the Sentry NDK libraries into your project so that the compiler can link the libraries during the build.

To do so, use the AndroidNativeBundle Gradle plugin that copies the native libraries from the Sentry NDK into the location that can provide links via the CmakeLists.txt configuration file.

First, we need to declare the dependency in the project build.gradle file:

build.gradle
Copied
buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        // Add the line below, the plugin that copies the binaries
        // https://github.com/howardpang/androidNativeBundle/releases
        classpath 'io.github.howardpang:androidNativeBundle:{version}'
    }
}

Once the dependency is declared, you can use it in the application build.gradle:

Copied
apply plugin: 'com.ydq.android.gradle.native-aar.import'

Then update the CmakeLists.txt configuration to link the Sentry NDK libraries:

Copied
# include paths generated by androidNativeBundle
include (${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK})
# change native-lib to your native lib's name
target_link_libraries(native-lib ${ANDROID_GRADLE_NATIVE_MODULES})

Now you can use the Sentry NDK API just by including the sentry.h in your code:

Copied
#include <jni.h>
#include <android/log.h>
#include <sentry.h>

#define TAG "sentry-android-demo"
extern "C" JNIEXPORT jstring JNICALL

Java_io_sentry_demo_NativeDemo_crash(JNIEnv *env, jclass cls) {
    __android_log_print(ANDROID_LOG_WARN, "", "Capture a message.");
    sentry_value_t event = sentry_value_new_message_event(
            /*   level */ SENTRY_LEVEL_INFO,
            /*  logger */ "custom",
            /* message */ "Sample message!"
    );
    sentry_capture_event(event);
}

Disable NDK Integration

You can disable the NDK integration by adding the following to your AndroidManifest.xml:

AndroidManifest.xml
Copied
<application>
    <meta-data android:name="io.sentry.ndk.enable" android:value="false" />
</application>

Using the SDK without the NDK

You can use Sentry's Android SDK without the Android Native Development Kit (NDK) by either:

  • Disabling the NDK
  • Using sentry-android-core, which doesn't contain the NDK and can be used separately, instead of sentry-android when adding the dependency. The minimal required API level for sentry-android-core is 14.

API Level Lower Than 16

To support the devices on the API level lower than 16, update your AndroidManifest.xml:

AndroidManifest.xml
Copied
<manifest>
    <!-- Merging strategy for the imported manifests -->
    <uses-sdk tools:overrideLibrary="io.sentry.android" />
</manifest>

With these changes the SDK will be enabled on all devices with API level ≥ 14 and the SDK with NDK will be enabled on all devices with API level ≥ 16.

Troubleshooting

If you are using sentry-android version earlier than 5.0, due to current limitations in how sentry-native works, it cannot identify native libraries loaded directly from .apk files. Instead, it needs to have access to the extracted libraries on the file system. This functionality is disabled by default when using an Android Gradle Plugin >= v3.6.0, and it needs to be enabled with the extractNativeLibs configuration option.

If you're using Android App Bundle, set android.bundle.enableUncompressedNativeLibs=false along with the extractNativeLibs configuration option.

Apart from this, sentry-native also uses tagged pointers internally. As a result, the Android SDK will not work out of the box on newer Android devices which have their own conflicting pointer tagging.

Example AndroidManifest.xml:

AndroidManifest.xml
Copied
<application
    android:allowNativeHeapPointerTagging="false"
    android:extractNativeLibs="true">
</application>

Example gradle.properties:

gradle.properties
Copied
android.bundle.enableUncompressedNativeLibs=false