JNI 基础- 使用 JNI 实现 Hello,World

作者: 毛先森 | 来源:发表于2019-08-05 14:46 被阅读6次

    前言

    结束了第一阶段 C++ 基础,接下来开始 JNI 基础的学习,经过对 JNI 学习资料的筛选,最后选中了
    南洋理工大学 JNI 教程,课程内容全英文的,刚好拿来锻炼一下阅读能力

    由于 Java 基于虚拟机运行,有跨平台的优点,而原生代码没有这一特性,所以我们要根据手机 cpu 类型来制作对应的库文件,Android 端常见的平台类型有 arm64-v8a,armeabi,armeabi-v7a,mips,mips64,x86,x86_64

    相关链接

    深入理解 System.loadLibrary

    南阳理工大学 JNI 教程

    android lib下不同的cpu类型

    Android NDK开发扫盲及最新CMake的编译使用

    如何在已有项目中进行NDK开发

    调用 native 代码

    在 JNI 代码中我们经常看到 System.loadLibrary 语句,这句话的含义是 Java 代码调用动态链接库,其实内部进行了方法指针强制转换等一系列操作,因为 Android 基于 Linux 内核,loadLibrary 内部封装的就是 Linux 平台加载 so 动态库文件的代码,网上有大神对 loadLibrary 源代码进行了分析.

    深入理解 System.loadLibrary

    JNI 的开发流程

    1. 使用 Java 编写声明 Native 方法的类
    2. 将 Class 文件编译成字节码
    3. 使用 javah -jni 指令生成 .h 头文件
    4. 使用 C/C++ 代码实现定义的方法
    5. 生成 so 动态库文件(windows 平台生成 dll,linux/unix 生成 so,macOs 生成 jniLib)
    6. Java 代码使用 so 动态库

    Hello,Word 程序

    NDK 的环境配置在网上一搜一大把,需要下载 LLDS,NDk 和 Cmake 工具,我们再这里就不做详细说明了.

    • 定义 native 方法

    首先创建 java 文件,定义原生代码的方法名以及返回值

    /**
     * @author : kai.mao
     * @date :  2019/8/5
     */
    public class JniUtil {
    
        // 定义 native 方法
        public native String sayHelloWorld();
    
        // 加载 so 动态库文件
        static {
    
            System.loadLibrary("HelloWord");
    
        }
    
    }
    
    
    • 使用 javah 指令生成 .h 头文件

    在 Terminal 中首先 cd 到该 java 所在的文件夹,然后使用 javah

    // 需要相对路径
    D:\TopAndroid\HelloJNI\app\src\main\java>javah com.bailun.kai.hellojni.JniUtil
    

    生成如下文件,并将该文件放到 main/cpp 文件夹中

    image.png
    • 根据头文件编写 cpp 文件

    在 cpp 下新建 xxx.cpp 文件,代码如下:

    //
    // Created by Admin on 2019/8/5.
    //
    
    
    #include "com_bailun_kai_hellojni_JniUtil.h"
    
    JNIEXPORT jstring JNICALL Java_com_bailun_kai_hellojni_JniUtil_sayHelloWorld
      (JNIEnv *env, jobject){
    
    
          return env->NewStringUTF("Hello,World!");
      }
    
    
    
    • 创建 CMakeLists.txt 文件
    cmake_minimum_required(VERSION 3.4.1)
    
    
    add_library( # Specifies the name of the library.
    # 这里是你so的名字。
                 HelloWord
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                  #这里是刚才 创建的c++ 代码的名字
                 src/main/cpp/HelloWorld.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 )
    
    target_link_libraries( # Specifies the target library.
    # 这里是你so的名字。
    
                           HelloWord
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    
    
    • 生成 so 文件

    使用 As Build 项目后,可在 cmake 目录下看到生成的 so
    文件

    image.png

    最终结果

    image.png

    相关文章

      网友评论

        本文标题:JNI 基础- 使用 JNI 实现 Hello,World

        本文链接:https://www.haomeiwen.com/subject/wbrmdctx.html