NDK development process

NDK development learning notes.

1. Write native methods in Java code. You can write the native method in the Activity or recreate a Java class. I wrote it here by re creating a Java class.

public class GetString {
    //native method
    public native String getString();
}

2. Create a jni directory under the main directory. Used to store header files (. h) and source files (. c).

Right click jni Directory - > New - > C / C + + source file to create header file and source file

Fill in the names of the header file and the source file in the pop-up window. Check Create an associated header to generate both the header file and the source file. If not checked, only the source file will be created. After creation, you can write C code in these two files. I don't like this way to create header files and source files.

 

Here is the second creation method.

After creating the jni directory, open Terminal and enter cd app/src/main/java,

Enter javah com.example.ndkdemo.GetString and press enter. com.example.ndkdemo.GetString is the full path of the class where you write the native method.

 cd app/src/main/java 

 javah com.example.ndkdemo.GetString

  After a moment, a header file will be generated under the app/src/main/java path

  Move this file to the jni directory and open it.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_ndkdemo_GetString */

#ifndef _Included_com_example_ndkdemo_GetString
#define _Included_com_example_ndkdemo_GetString
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_ndkdemo_GetString
 * Method:    getString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject); This is the corresponding method generated by the native method in the jni layer. Note Java_ com_ example_ ndkdemo_ GetString_ The method name of getString should not be modified. The naming format of this method is Java_ The full pathname of the class_ Method name, middle_ separate. Using the first method to create header files and source files, you need to write the method name yourself, which is easy to make mistakes.

Then, right-click jni Directory - > New - > C / C + + source file to create a source file, as long as you don't check Create an associated header.

3. Method in header file   JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject); Copy to the source file and remove JNIEXPORT and JNICALL to implement this method. Note that you need to import the header file to #include "GetString.h".

#include "GetString.h"

jstring Java_com_example_ndkdemo_GetString_getString
        (JNIEnv *env, jobject jobj) {
    return (*env)->NewStringUTF(env, "asdfghjkl");
}

  4. Create CMakeLists.txt in the app directory

The contents of CMakeList.txt are as follows

# 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.
        GetString

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        src/main/jni/GetString.c
        src/main/jni/GetString.h
        )

# 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.

#This function means to alias the log Library of the system and name it log lib
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.

#This function means that the previously named library is link ed together
target_link_libraries( # Specifies the target library.
        #        Hello
        #        JavaCallC
        GetString

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

  5. Add ndk configuration information under the Android - > defaultconfig node of build.gradle(app)

ndk {
            abiFilters "armeabi-v7a" //cpu type, the so file corresponding to the cpu will be generated
        }

      Configure CMakeLists information under the android node

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

6. Load dynamic link library

public class JNI {

    //Load dynamic link library
    {
        System.loadLibrary("Hello");
    }

    public native String sayHello();
}

7. Use

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String result = new JNI().sayHello();
        Log.d(TAG, "result -> " + result);
    }
}

Keywords: Android JNI NDK

Added by christofurr on Mon, 22 Nov 2021 08:46:43 +0200