JNI和NDK

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是一种协议,NDKAndroid开发JNI的工具包。

JNIjava native interface : java本地开发接口

通过jni就可以让javaC/C++代码实现互调。

为什么使用JNI

  • native coder执行高效:大量的运算(极品飞车),万能解码(ffmpeg),Opengl(3D渲染)。
  • 通过jni技术,可以拓展Android手机的功能-WiFi热点
  • 代码的复用:ffmpegopencv(人脸识别库),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

下图中箭头所指的三个就是我们需要下载的。

JNI和NDK_第1张图片
image

在这个图中我们可以查看 NDK下载的位置。
我的下载位置是 D:\Android\Sdk\ndk-bundle
JNI和NDK_第2张图片
image

1. 创建项目

这里创建的是JNI_NDK

2. 创建jni文件夹

右键 ---> src ---> new ---> Folder ---> JNI Folder

JNI和NDK_第3张图片
创建jni文件夹.png

jni文件夹的路径

JNI和NDK_第4张图片
jni文件夹路径.png

可以看到jni文件夹与java文件夹是同一级的

3.创建JNI类
public class JNITest {

    static {
        System.loadLibrary("JniLib");
    }

    public native String getString();

}
4. 生成头文件

点击 File ---> Settings ---> Tools ---> External Toosl
如下图所示:

JNI和NDK_第5张图片
生成头文件1.png

如果没有配置过将不会显示,我的是配置过的,所以显示有两个。
点击加号,出现下面的界面


JNI和NDK_第6张图片
生成头文件2.png
JNI和NDK_第7张图片
生成头文件3.png

配置好这两个以后,就可以生成.h头文件了。按照下图的操作,


JNI和NDK_第8张图片
生成头文件4.png

完成后,就可以在JNI目录下看到生成的.h头文件了


JNI和NDK_第9张图片
生成头文件5.png
4.创建JniLib.cpp,Android.mk,Application.mk文件
JNI和NDK_第10张图片
生成头文件6.png

复制.h文件内容到JniLib.cpp并修改,如下: 此文件为JNI内容文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* 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文件,如下图:

JNI和NDK_第11张图片
NDK1.png
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,如下图所示:


JNI和NDK_第12张图片
NDK2.png

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() );
            }
        });

    }
}

你可能感兴趣的:(JNI和NDK)