How to add JNI (native C / C ++ code) to an existing Android Studio project

As the title says - how to add custom code to an existing Android Studio project without breaking the current project including gradle and proguard settings?

+14


source to share


2 answers


Follow these steps from your existing project:

1. Modify build.gradle (module app) so it looks like this (many 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 change at least the values ​​with "--value--" to match yours.

2. Modify build.gradle (Project)

where it is written something like this:

dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
}

      

to that:

dependencies {
    classpath 'com.android.tools.build:gradle-experimental:0.9.3'
}

      

The number in my example 0.9.3 is the latest gradle-experimental version which can be found here . Eventually change the Gradle version in gradle-wrapper.properties to the version recommended by Android Studio if you haven't already.

3. Move your Proguard settings file



proguard-android-optimize.txt

in app/proguard-android-optimize.txt

4. Add call from Java

like this

static {
    System.loadLibrary("--c-file--");
}
private native byte my_jni(Context context, byte[] mByte, int i);

      

changes according to your needs. The above example loads a c file (write it without extension) - the same one declared in the gradle file and calls the function my_jni passing the application context, some byte array and some int, expecting the functions to return a byte.

5. Create a function in JNI:

Your function name is now highlighted in red - let Android Studio create it. Create function...

by clicking on the red light in the row. This creates a function in your c file and changes focus to it.

Done

Further reading here .

Hints:

  • Take care free

    that whatever you use malloc

    is ReleaseByteArrayElements

    for everyone GetByteArrayElements

    , etc.

  • Take care of how to correctly return some dangerous values ​​from C to Java like arrays and strings

+6


source


Since Android Studio 3.1 it is possible in a simple way:

1. Create a folder cpp

inside app\src\main

.

2. Create a file <YOUR_FILE_NAME>.cpp

folder app\src\main\cpp

(for example native-lib.cpp).

3. Add the file CMakeLists.txt

to the folder app

.

This library file name should contain the file path .cpp

and some other parameters, for example (from a new blank 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 application) a tag externalNativeBuild

with a link to CMakeLists.txt

the section android

:



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 application) a tag externalNativeBuild

with a tag cmake

in the section defaultConfig

:

...
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 a "base" file build.gradle

also available in a new, empty Android Studio project with C ++ support)

6. Resync Project with Gradle files

By clicking Sync Project Sync Project button on Toolbaron the toolbar. NB! In Android Studio 3.3, this is an icon Android Studio 3.3 Sync Project button on Toolbar.

Also, take a look at the official tutorial .

+18


source







All Articles