Android JNI and NDK learning (1): NDK learning

Overview

If you want to learn JNI and NDK, you must first know what JNI and NDK are and what they do, so that you can learn and understand JNI and NDK better. This article is mainly used as a study note in case you forget it in the future.

JNI introduction

Definition: JNI is the Java Native Interfacejava local interface

Role: Allow java to interact with other types of languages ​​(such as C and C++)

Note: JNI belongs to java and has nothing to do with android

NDK introduction

Definitions: NDK That Native Development Kitis an android of a development kit

Function: rapid development of C/C++ dynamic library, and automatically package so and applications into APK

Note: NDK belongs to android and has nothing to do with java

The connection between JNI and NDK

 可以通过NDK工具  在Android中使用JNI与本地代码(C、C++)进行交互
 
 JNI是实现的目的,NDK是实现JNI的手段
 
 即在Android 的开发环境中(Android Studio)通过NDK实现JNI的功能

Use Android Studio to create an NDK project

Since Android Studio 2.2 and above has integrated NDK internally, it only needs to be configured inside Android Studio. The version I currently demonstrate is 3.5.3

Insert picture description here
Insert picture description here
Insert picture description here

After these three steps, an NDK project can be automatically generated
Insert picture description here

Compared with ordinary projects, this folder is more, which contains native-lib.cppC, C++ code, and CMakelist.txtcompile scripts.

Let’s analyze this project

MainActivity

public class MainActivity extends AppCompatActivity {
    
    

    // Used to load the 'native-lib' library on application startup.
    static {
    
    
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

First load native-lib.so, then call the stringFromJNImethod in so, and finally display the value returned by this method TextViewon

Among them native-lib.so, the name of this library is specified in CMklist.txt, which stringFromJNIis a java nativemethod, and its real implementation is native-lib.cppin

native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_taobao_alinnkit_ndk1_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    
    
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

The above public native String stringFromJNI()implementation is here, so how to determine which method in Java the Native method corresponds to in C, here is static registration, that is Java包名类名_方法名, the form, and then continue to talk about other registration methods

The entire call flow

  • Gradle calls the external build script CMklist.txt
  • CMake native-lib.cppcompiles the C++ source file into a native-lib.sodynamic library according to the commands in the script and compiles it into the APK
  • First load at runtime native-lib.so, then call the stringFromJNImethod in so, and finally display the value returned by this method TextViewon

Configure Gradle to support NDK

Let's first look at the gradle of the project created above

Insert picture description here

Inside the red box which is configured NDK, that needs to be configured externalNativeBuild {}to add to gradle and use cmake {}to configure

We can see that two places in Gradle are used externalNativeBuild {}, one on the defaultConfiginside and one on the defaultConfigoutside

  • In the defaultConfigoutside of the externalNativeBuild {}block of code cmakedeveloped CMakeList.txtpath
  • In defaultConfigwhich the externalNativeBuild {}block of code cmakeis mainly to fill CMakecommand parameters

CMakeLists.txt file analysis

# 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).
        native-lib.cpp)

# 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})

cmake_minimum_required(VERSION 3.4.1)

Set the minimum version of CMake

add_library

The first parameter: set the name of the library. The
second parameter: set the type of library, SHARE dynamic library .so suffix, STATIC static library .a suffix.
Third parameter: the relative path of the source file

You can define multiple libraries, CMake will build them, and Gradle will automatically put the shared libraries into the APK

find_library

Find an NDK library and store the path of the library in a variable. For example, in the example, find a log library in NDK (a log library that supports android), and store the variable in the log-lib variable

target_link_libraries

Associate library, associate the specified library, such as the example above, the first parameter: the target library, and the second parameter: link the target library to the log library and include it in the NDK.

This is the most basic CMakeLists.txt, in fact, it can be very powerful, for example, you can customize commands, find files, set variables, etc., it is recommended to refer to the CMAKE manual

reference:

https://blog.csdn.net/carson_ho/article/details/73250163

https://blog.csdn.net/afei__/article/details/80897404

https://www.jianshu.com/p/b4431ac22ec2

Guess you like

Origin blog.csdn.net/qq_34760508/article/details/106478299