Like the title says - how to add native code to existing Android Studio project, without breaking the current project, including gradle and proguard settings?
Using Android Studio 2.2 and higher, you can use the NDK to compile C and C++ code into a native library and package it into your APK using Gradle, the IDE's integrated build system. Your Java code can then call functions in your native library through the Java Native Interface (JNI) framework.
To Install and Use C/C++ compiler in Termux (in Termux clang is the C/C++ compiler) , Download & Install Termux from : Play Store. After Installing execute this command pkg install clang. After Successfully installing clang you can compile C/C++ scripts.
JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).
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.
Follow this steps from your existing project:
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.
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.
proguard-android-optimize.txt
to app/proguard-android-optimize.txt
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.
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.
Further reading here.
Tips:
Take care to free
everything you malloc
, ReleaseByteArrayElements
for every GetByteArrayElements
and so on
Take care how to properly return some dangerous values from C to Java, like arrays and Strings
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With