Recently, there are more and more applications related to the Internet of Things, and for developers, the frequency of JNI calls and even NDK development is getting higher and higher, so I will write about my learning experience here, and I hope it will be helpful to those who start learning.
Ready to work:
1. Android Studio is above 2.3 and has support for C++ code, so we configure relevant content to help understand C++ code or methods in JNI in the future. First, open the sdk manager, download
these two tools, and then Check the support for C++ when you create a new project
2. NDK download, you can download it yourself, or you can download it directly in Android Sudio, click File -> OtherSettings -> Default Project Structure..., download in NDK, after finishing the project's local.properties will have ndk configuration information
Let's start to enter the topic, starting with a simple project that returns a string from C++
Create a new ndklibrary model as library, and then create a java class as the declaration of the native method called by jni,
public class StringJNI { static { System.loadLibrary("StringJNI"); } public native String getHelloString(); }
The class is very simple, loads a local library, here this library is what we want to generate, and then defines a native method to get the string, and then build.gradle configures the compilation information
defaultConfig{
ndk{
moduleName "StringJNI" //so file name, may not be the same as the above class name
abiFilters 'armeabi-v7a', 'arm64-v8a' // 'x86', 'x86_64' 这里如果是写‘armeabi’,在新的NDK里
//是不支持导致编译不过
}
}
然后能过javah命令开生成头文件,AS下打开terminal,输入以下命令
这时,如果提示javah不是内部命令,就先去配置环境变量,在有些类里,不加-encoding会报
编码GBK的不可映射字符。
然后就会在当前目录下生成一个头文件com_example_qjl_ndklibrary_StringJNI.h,这个文件的命名是固定的,包名加类名用_连接组成。然后new一个jni folder,把头文件放进去,并创建一个.cpp的C++类,引入头文件,由于前面加了C++的支持,这时我们打#in时,就会有代码补全的提示
有了这些提示,对我们写C++的代码也很有帮助,然后写完C++的方法
#include "com_example_qjl_ndklibrary_StringJni.h"
JNIEXPORT jstring JNICALL Java_com_example_qjl_ndklibrary_StringJni_getHelloString(JNIEnv *env, jobject jobject1) {
return (env) -> NewStringUTF("Hello JNI !");
}
这里先不考究代码的详细信息,只要知道返回了一个String,这个String是方法NewStringUTF转化的java的String。
这时代码的编写就完成了,然后编译代码,成功后会在
build的ndk目录下有相应的so库
如果项目是依赖于整个ndklibrary工程的话,so库不用管,如果是生成jar包用的话,就要把so库放到当前的项目的libs文件夹下。
最后在要使用的地方
new StringJni().getHelloString()就可以了,由于后来类重命名过,所以有些是StringJni有些是StringJNI,这个大家不用理会,知道就好。
好了,整个JNI调用的步骤大概就这样子,希望对大家有所帮助,忘后再详细说说怎样配置,编译so库和一些jni里常用的函数等内容。