Android JNI/NDK入门教程第一章:环境的配置与Demo编译

一、背景

        很多开发者在开发过程中经常遇到有人问你JNI或者NDK的问题,而且JNI和NDK是非JAVA语言,需要C++来完成。C++在处理多媒体文件具有一定的有事,所以Java也提供了一个方法就是对NDK的支持。

很多人可能还在迷茫如何去编译如何去调用,下面我将讲解一下如何如入门

二、NDK的环境搭建

如果我们通过AndroidStudio来开发,那么只要设置了ndk.dirs=""即可。

1.Java环境:正常的classpath和javahome的配置

2.ndk:在androidstudio中配置好了ndk环境

三、AndroidStudio的配置

上面是开发环境的配置,接下来就是关于编译的配置

1.build.gradle:配置编译环境

在defaultConfig节点新增:

        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
        ndk {
            abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
        }

主要配置编译环境和nkd的输出

2.jni编译文件配置

我们采用的是cmake进行编译了,所以在android{}节点下配置编译即可

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.22.1"
        }
    }

path:需要执行的cmake地址,正常在main下面cpp文件下,用来编译链接cpp文件的

三、JNI类的编译与连接流程

上面讲解了编译配置,那么我们开始做编译类的工作了。正常我们会在main下新建一个cpp文件夹,用来专门放cpp文件和cmake编译脚本的。

1.新增native类:

随便在包下新增一个类作为测试:

public class TestJni {


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

    public native String getMessage();
}

Java和kotlin有所区别,kotlin的native不是native,是external。

2.编译生成h文件

2.1第一步先通过javac对java文件进行编译

找到目标文件所在的根目录,

jni> javac .\TestJni.java,执行完会生成一个class文件

2.2生成.h文件(jni文件)

通过javah -jni 类,这个命令是对刚才编译完的class导出为jni文件。这个命令要回到src节点下

在src节点下,在终端通过命令来编译:javah -jni packagename.className

一定要输入完整的包名和类名,如果Test在包com.jni.test下,那么就是javah -jni com.jni.test.Test

会在src下面生成一个.h的c文件,这个文件就是我们要用到的jni信息文件。这个文件名一般是就是包名和类型的组合

3.cpp文件的编写

通过上面我们基本完成了jni的前期准备,接下来就是cpp文件的创建,jni是通过c++来创建的,刚才的c文件其实是一个没有函数体的函数声明,我们需要自己通过c++文件来实现函数体

3.1我们先把生成的信息放到cpp文件夹中

正常编译一个cpp需要至少一个cmake和cpp。h文件可以有可以没有,如果你是通过jni生成的,需要导入。

#include "com_love_lovestudy_testdemo_jni_TestJni.h"
JNIEXPORT jstring JNICALL Java_com_love_lovestudy_testdemo_jni_TestJni_getMessage
        (JNIEnv* env, jobject cls){
        const char a[]="ssssss";
    return env->NewStringUTF(a);
}

我在test-jni中实现了h文件的函数体,返回了一个字符串。

4CMakeLists.txt的配置与编译

我们是直接通过cmake编译,不需要mk文件参与,所以所有的配置信息都在这里面,配置的核心就是:

1.so文件输出的位置
#so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
        ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

我们配置了输出在cpp文件统计目录的jnilibs文件夹中

2.so文件名
#1. 添加自己的so库test-lib,设置一个名字,输出就是这个名字
add_library( # Sets the name of the library.
        test_jni

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        test_jni.cpp)

test_jni就是文件名,这个文件名和连接需要用到,test_jni.cpp是我们需要编译的目标cpp

3.cpp文件的导入

参考2,其实这两个就是导入和设置一个文件名,输出的so文件就是这个名字

4.链接cpp文件
target_link_libraries( # Specifies the target library.
        test_jni

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

连接的test_jni就是上面3的文件连接别名,这两个一定要一致,否则无法生成。

通过这个四部我们基本能生成自己的so文件了,一个cmake只能链接一个cpp文件,只能生成一个so文件,所以cmake与cpp是1v1的关系,后面会讲解多个cmake管理。

完成的如下:
#so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
        ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

#版本
cmake_minimum_required(VERSION 3.4.1)



#1. 添加自己的so库test-lib,设置一个名字,输出就是这个名字
add_library( # Sets the name of the library.
        test_jni

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        test_jni.cpp)


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 )

#add 库的名字和target的要一致,因为target链接add的文件
target_link_libraries( # Specifies the target library.
        test_jni

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})



5.生成so文件

生成so文件需要把cmakelist插入build.gradle文件。

通过build->make project或者rebuild project。执行完会生成如下

生成的so文件名:一般都是lib+你自己定义的名字

四、测试so的正确性

1.在native类中加载so文件

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

注意:我们生成的so文件名为libtest_jni.so,但是我们不需要lib这个前缀,只需要把我们在cmake中配置的名字加载进去即可。

2.正常调用

 testJni=new TestJni();
            textView.setText(testJni.getMessage());

五、总结

        通过以上步骤,我们已完成了JNI/NDK的搭建与配置完毕,大家可以很清楚的看到so文件的生成整个过程。已基本掌握的JNI的编译与生成整个流程,包括问题的处理基本都有。可以很直观的定义自己的JNI文件

  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值