Skip to main content

Quick start guide

This tutorial guides you through creating your first Android application with native C++ code. You’ll build a simple “Hello from C++” app that demonstrates how Java/Kotlin code interacts with native code through JNI (Java Native Interface).

Prerequisites

Before starting, ensure you have:
  • Android Studio installed with NDK and CMake
  • Basic knowledge of Android app development
  • Basic C++ knowledge (helpful but not required)
If you haven’t installed the NDK yet, see the installation guide.

Create your first native app

1

Create a new project with native support

Open Android Studio and create a new project:
  1. Click File > New > New Project
  2. Select Native C++ template
  3. Click Next
  4. Configure your project:
    • Name: HelloNDK
    • Package name: com.example.hellondk
    • Language: Kotlin (or Java)
    • Minimum SDK: API 21 or higher
  5. Click Next
  6. Choose C++ Standard: C++14 or higher
  7. Click Finish
Android Studio creates a project with native code support pre-configured.
2

Explore the project structure

Your project now contains both Java/Kotlin and C++ code:
Key files:
  • native-lib.cpp: Your C++ source code
  • CMakeLists.txt: CMake build configuration
  • MainActivity.kt/java: Loads and calls native code
3

Examine the native code

Open app/src/main/cpp/native-lib.cpp. You’ll see a JNI function:
This function:
  • Is called from Java/Kotlin code
  • Returns a string created in C++
  • Uses JNI to convert C++ string to Java string
The function name follows JNI naming convention: Java_<package>_<class>_<method>
4

Examine the CMake configuration

Open app/src/main/cpp/CMakeLists.txt:
This configuration:
  • Creates a shared library named native-lib
  • Compiles native-lib.cpp
  • Links the Android log library
5

Examine the Kotlin/Java code

Open MainActivity.kt (or MainActivity.java):
The code:
  • Loads the native library with System.loadLibrary()
  • Declares the native method with external (Kotlin) or native (Java)
  • Calls the C++ function like any other method
6

Build and run the app

  1. Connect an Android device or start an emulator
  2. Click Run (green play button) or press Shift+F10
  3. Wait for the build to complete
  4. The app displays “Hello from C++” on the screen
The first build may take longer as CMake compiles the native code for multiple architectures (armeabi-v7a, arm64-v8a, x86, x86_64).

Customize your native code

Now let’s modify the native code to perform a simple calculation.
1

Add a new native function

In native-lib.cpp, add a new function that adds two numbers:
This function:
  • Takes two integers as parameters
  • Returns their sum
  • Uses jint (JNI integer type)
2

Declare the method in Kotlin/Java

In MainActivity.kt, add the method declaration:
3

Call the native function

Update onCreate to call the new function:
4

Build and run again

Run the app again. You should now see:

Add logging from native code

Logging is essential for debugging native code. Let’s add Android logging support.
1

Include the log header

In native-lib.cpp, add the Android log header:
2

Add logging to your function

Update the addNumbers function:
3

View logs

Run the app and check Logcat in Android Studio:
  1. Open Logcat tab at the bottom
  2. Filter by “NativeLib”
  3. You’ll see the log messages from C++:

Understanding JNI types

When working with JNI, you need to understand type mappings between Java and C++:
Always use JNI types in your native function signatures. Using regular C++ types will cause runtime errors.

Build system configuration

The build.gradle file contains NDK configuration:
Building for fewer ABIs reduces APK size but limits device compatibility. Most production apps target armeabi-v7a and arm64-v8a.

Debugging native code

Android Studio provides full debugging support for native code:
1

Set breakpoints

Open native-lib.cpp and click in the left gutter to set a breakpoint.
2

Debug the app

Click Debug (bug icon) instead of Run. The debugger will pause at your breakpoint.
3

Inspect variables

Use the Variables pane to inspect values, step through code, and evaluate expressions.

Common issues and solutions

UnsatisfiedLinkError

If you see UnsatisfiedLinkError: No implementation found:
  • Verify the native function name matches the JNI naming convention
  • Ensure System.loadLibrary() is called before the native method
  • Check that CMakeLists.txt includes your .cpp file

Build errors

If the native build fails:
  • Check Build tab for CMake error messages
  • Ensure NDK and CMake are installed via SDK Manager
  • Verify CMake version in CMakeLists.txt matches installed version

Missing symbols

If you get linker errors about missing symbols:
  • Add required libraries to target_link_libraries in CMakeLists.txt
  • For Android APIs, use find_library() to locate system libraries

Next steps

Congratulations! You’ve built your first native Android application. Here’s what to explore next:

Build systems

Learn advanced CMake and ndk-build configurations

JNI guide

Deep dive into Java Native Interface programming

Performance

Optimize your native code for maximum performance

Debugging

Master native debugging and crash analysis

Additional resources