JNI入坑
索引:
- 旧 NDK 使用姿势(AS 2.2 以下 参考链接:Create hello-JNI with android studio)
- 新 NDK 使用方法(AS 2.2及以上 参考链接:Add C and C++ Code to Your Project)
参考:
JNI Tips
(链接均需VPN)
旧 NDK-build:
简单来说分这么几步:
- 添加ndk库支持
- 在 gradle.properties中添加:
android.useDeprecatedNdk=true
- 在 app级build.gradle中添加:
defaultConfig {
ndk {
moduleName "test-jni" // name the jni lib you want to add
}
}
- 创建load 静态块,添加待实现native api
public class JniTest {
static {
System.loadLibrary("test-jni");
}
public native String getMsgFromJni();
}
在 目标api所在行停留一会,会出现红色灯泡提示按钮,点击图标,会有Create Function Java_%full class name%_getMsgFromJni
选项出现;点击之后会自动创建一个与java目录并列的cpp目录,并在目录下生成test-jni.c
文件
具体代码如下:
#include <jni.h>
JNIEXPORT jstringJNICALL
Java_com_zealens_face_jnitest_JniTest_getMsgFromJni(JNIEnv
*env, jobject instance)
{
// TODO
return (*env)->NewStringUTF(env, returnValue);
}
说明:
- 对于第3行代码:
AS生成的代码有错误,需将JNICALL与前面的jstring隔开; - 将returnValue修改为常量值(eg:"hello")
至此,build之后调用API就能得到刚才填入的hello值。
新CMake
AS现在默认的C++工具已经修改为CMake(需要在SDK-Tools中安装CMake、LLDB、NDK),旧的ndk-build库也可以手动导入
准备工作:
- 如果有则移除:
// Remove this line
android.useDeprecatedNdk = true
- install build tools
(略:创建新的C++support Application)
- 向现有项目添加C/C++ 代码:
a. 新建cpp目录;
b. 添加cpp文件,代码如下:
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_%your test class full name%_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
在欲链接cpp的根目录中(与build.gradle同级)创建文件:CMakeLists.txt
,键入如下代码:(各API含义见参考链接末尾部分,或 CMake command)
# 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 )
# 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} )
之后,在同一模块目录上单击右键,选择link c++...
,选中欲链接的cpp文件,build.gradle就会生成如下代码:(android模块中)
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
此时再调用相应API就可以看到效果了:
public class CppTest {
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
}
pay attention to the lib name
高阶设置请参考手册,这里也只是介绍一个最小的CMake环境
关注公众号“夕识”,雕刻时光,雕刻思维
网友评论