How to add JNI (C/C++ native code) to existing Android Studio project
Follow this steps from your existing project:
1. Modify build.gradle (Module app) to look like this (a lot changes!):
apply plugin: 'com.android.model.application'
model {
android.signingConfigs {
create ("myConfig") {
keyAlias '--your-key-alias--'
keyPassword '--key-password--'
storeFile file('--/path/to/keystore.jks--')
storePassword '--store-password--'
}
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "--your.app.name--"
minSdkVersion.apiLevel 19
targetSdkVersion.apiLevel 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles.add(file('proguard-android-optimize.txt'))
proguardFiles.add(file('proguard-rules.pro'))
signingConfig = $("android.signingConfigs.myConfig")
}
}
ndk {
moduleName "--c-file--"
ldLibs.addAll(["android", "log"])
}
}
android.dexOptions {
javaMaxHeapSize "2048m"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.1'
}
You can copy/paste the above code and modify at least the values with "--value--" to match yours.
2. Modify build.gradle (Project)
where it says something like this:
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
to this:
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.9.3'
}
The number in my example 0.9.3 is the latest version of gradle-experimental to be found here. Eventually change your gradle version in gradle-wrapper.properties to the version recommended by Android Studio if you did not already.
3. Move your proguard settings file
proguard-android-optimize.txt
to app/proguard-android-optimize.txt
4. Add the call from java
like this
static {
System.loadLibrary("--c-file--");
}
private native byte my_jni(Context context, byte[] mByte, int i);
changing to your needs. The example above loads the c-file (write it without the extension) - the same one declared in the gradle file, and calls the function my_jni, passing the application's Context, some byte array and some int, expecting that the functions returns a byte.
5. Create the function in JNI:
Now the name of your function is highlighted in red - allow Android Studio to create it Create function ...
with clicking on the red lamp on the row. This creates the function in your c file and changes focus to it.
Done
Further reading here.
Tips:
Take care to
free
everything youmalloc
,ReleaseByteArrayElements
for everyGetByteArrayElements
and so onTake care how to properly return some dangerous values from C to Java, like arrays and Strings
Since Android Studio 3.1 its possible easy way:
1. Create cpp
folder inside app\src\main
.
2. Create <YOUR_FILE_NAME>.cpp
file in app\src\main\cpp
path (e.g. native-lib.cpp)
3. Add CMakeLists.txt
file to app
folder.
In that file name of the library, .cpp
file path and some other settings should be defined, e.g. (from new, empty Android Studio Project with C++ support):
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
^^^^^^^^^^^^^^
YOUR_CPP_FILE_NAME
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
4. Add to build.gradle (Module app) externalNativeBuild
tag with reference to CMakeLists.txt
into android
section:
android {
compileSdkVersion 26
defaultConfig {
...
}
buildTypes {
...
}
externalNativeBuild { <--- these lines should be added
cmake { <--- these lines should be added
path "CMakeLists.txt" <--- these lines should be added
} <--- these lines should be added
} <--- these lines should be added
}
5. Add to build.gradle (Module app) externalNativeBuild
tag with cmake
tag into defaultConfig
section:
...
defaultConfig {
applicationId "<YOUR_APP_ID>"
minSdkVersion 26
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { <--- these lines should be added
cmake { <--- these lines should be added
cppFlags "" <--- these lines should be added
} <--- these lines should be added
} <--- these lines should be added
}
...
(example of "basic" build.gradle
file also available in new, empty Android Studio project with C++ support)
6. Resync Project with Gradle files
By clicking Sync Project in the toolbar. NB! In Android Studio 3.3, the icon is .
Also, take a look at Official Tutorial.
PS. If files not shown in cpp
folder:
try File/Invalidate Caches & Restart
as Thinh Vu mentioned in his comment.