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 Interface
java 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 Kit
is 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
After these three steps, an NDK project can be automatically generated
Compared with ordinary projects, this folder is more, which contains native-lib.cpp
C, C++ code, and CMakelist.txt
compile 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 stringFromJNI
method in so, and finally display the value returned by this method TextView
on
Among them native-lib.so
, the name of this library is specified in CMklist.txt, which stringFromJNI
is a java native
method, and its real implementation is native-lib.cpp
in
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.cpp
compiles the C++ source file into anative-lib.so
dynamic library according to the commands in the script and compiles it into the APK - First load at runtime
native-lib.so
, then call thestringFromJNI
method in so, and finally display the value returned by this methodTextView
on
Configure Gradle to support NDK
Let's first look at the gradle of the project created above
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 defaultConfig
inside and one on the defaultConfig
outside
- In the
defaultConfig
outside of theexternalNativeBuild {}
block of codecmake
developedCMakeList.txt
path - In
defaultConfig
which theexternalNativeBuild {}
block of codecmake
is mainly to fillCMake
command 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