NDK和JNI基础
NDK
Native Development Kit是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C/C++的动态库,并能自动将so和java一起打包成apk。
JNI
Java Native Interface标准是java平台的一部分,JNI是Java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用C/C++代码,C/C++的代码也可以调用java代码。
NDK可以为我们生成了C/C++的动态链接库,JNI是java和C/C++沟通的接口,两者与Android没有半毛钱关系,只因为Android是java程序语言开发,然后通过JNI又能与C/C++沟通,所以我们可以使用NDK+JNI来实现Java + C的开发方式
JNI
是一种协议,NDK
是Android
开发JNI
的工具包。
JNI
:java native interface
: java
本地开发接口
通过jni
就可以让java
与C/C++
代码实现互调。
为什么使用JNI
?
-
native coder
执行高效:大量的运算(极品飞车),万能解码(ffmpeg
),Opengl
(3D渲染)。 - 通过
jni
技术,可以拓展Android
手机的功能-WiFi
热点 - 代码的复用:
ffmpeg
,opencv
(人脸识别库),7-zip
- 使用场景:考虑特殊情况(效率/操作硬件)
NDK
Native Develop Kits
:本地开发工具包
Android
提供的用来做JNI
开发的工具包
为什么使用NDK
?
- 提高
JNI
开发的效率 - 生成代码
- 代码提示
- 多平台交叉编译
环境配置可以参考这个文章https://blog.csdn.net/yao_94/article/details/79151804
1. Android NDK开发
先介绍一下我的软件版本
- JDK 1.8
- Android Studio 3.1
在使用NDK
开发的时候,先要把几样工具下好。
- NDK
- CMake
- LLDB
下图中箭头所指的三个就是我们需要下载的。
在这个图中我们可以查看
NDK
下载的位置。我的下载位置是
D:\Android\Sdk\ndk-bundle
1. 创建项目
这里创建的是JNI_NDK
2. 创建jni文件夹
右键 ---> src
---> new
---> Folder
---> JNI Folder
jni文件夹的路径
可以看到jni
文件夹与java
文件夹是同一级的
3.创建JNI类
public class JNITest {
static {
System.loadLibrary("JniLib");
}
public native String getString();
}
4. 生成头文件
点击 File ---> Settings ---> Tools ---> External Toosl
如下图所示:
如果没有配置过将不会显示,我的是配置过的,所以显示有两个。
点击加号,出现下面的界面
配置好这两个以后,就可以生成.h头文件了。按照下图的操作,
完成后,就可以在JNI目录下看到生成的.h头文件了
4.创建JniLib.cpp,Android.mk,Application.mk文件
复制.h文件内容到JniLib.cpp并修改,如下: 此文件为JNI内容文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <com_study_wumeng_jni_ndk_JNITest.h>
/* Header for class com_study_wumeng_jni_ndk_JNITest */
/*
* Class: com_study_wumeng_jni_ndk_JNITest
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_study_wumeng_jni_1ndk_JNITest_getString
(JNIEnv * env, jobject jobject){
return (*env).NewStringUTF("成功调用JNI内容");
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniLib
LOCAL_SRC_FILES =: JniLib.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_MODULES := JniLib
APP_ABI := all
5. 修改app下的build.gradle文件,如下图:
ndk{
moduleName "JniLib"
// abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定的三种abi体系下的so库
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir "src/main/libs"
}
6. 在项目下的gradle.properties中加上下面这条语句:
#兼容老的NDK
android.useDeprecatedNdk=true
7. 执行ndk-build:
前面我们已经配置过了,选中JNI类的右键---> New ---> External Tools ---> ndk-build,如下图所示:
8. 调用so文件
public class MainActivity extends AppCompatActivity {
private Button btn;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button);
textView = findViewById(R.id.text);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("结果: " + new JNITest().getString() );
}
});
}
}