Android JNI 开发

0.241字数 739阅读 32

一、JNI 与 Android

JNI 是 Java 提供的用于在跨平台系统中,与系统本地代码进行交互的一层应用程序接口。在 Android 中,同样支持 JNI 开发,通过 Android 提供的 NDK 工具,可快速构建 JNI 开发环境,并且可以快速整合到 Android 项目中。

JNI 编译出的 .so 文件具有较高的安全性,反编译难度高,在一些涉及到安全层面的场合,可以考虑使用 JNI 编程。在 Android 平台,JNI 编程主要依赖于 C 或 C++ 编程环境。

二、JNI 开发流程

集成 NDK 工具
在 Android 平台进行 JNI 开发,需要集成 NDK 工具,该工具可直接通过 Android Studio 相关管理界面下载、配置,这里不再累述。

Android NDK 配置

声明 native 方法
在项目中创建一个类,并声明相关 native 方法。

public class JNIs {
    public static native String getString();
}

编译并生成 .h 头文件
在 Android Studio 中直接 build 或者通过 javac 命令生成该类的 class 文件。build 命令自动生成的 class 文件夹路径如下图所示:

通过 build 自动生成 class 文件

也可以通过 javac 指定生成 class 文件的路径,定位到 java 类所在路径,通过如下命令将 class 文件生成到该目录下:

javac JNIs.java

若想指定 class 文件的输出目录,只需添加 -d 参数即可:

javac -d [目录] JNIs.java

生成 class 文件后,通过 java 将 .h 头文件输出,添加 -d 参数可将头文件输入至指定目录:

javah -d ../jni com.example.demo.mylibrary.JNIs

自动生成的 .h 头文件中的方法名称已严格按照指定规则命名,不能随意修改。

实现 native 方法
在相同的目录下新建 cpp 文件,文件名自定义,include 之前生成的 .h 文件,并实现相关方法:

//
// Created by me on 2019-08-18.
//
#include "com_example_demo_mylibrary_JNIs.h"
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_com_example_demo_mylibrary_JNIs_getString
        (JNIEnv * env, jclass clazz) {
    return env -> NewStringUTF("hello, jni!");
}

在 build.gradle 文件中声明 JNI module 信息:

android {
    // ...
    defaultConfig {
        // ...
        ndk {
            moduleName "jniTest"
            abiFilters "armeabi","armeabi-v7a","x86"
        }
    }
}

执行 build,Android Studio 会在项目的 build 文件夹下自动生成对应的 Android.mk 文件,无需手动配置。同时,对应的 .so 文件也被自动生成了。

.so 文件和 Android.mk 文件

使用 so 库
生成 .so 之后,需要将该文件和对应声明 native 方法的类一起 copy 至调用方项目环境中。并在使用该库的地方做如下声明:

public class JNIs {

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

    public static native String getString();

}

loadLibrary() 方法传入的 libName 参数严格按照在 build.gradle 文件中声明的 moduleName 为准。

更多 Android NDK 的相关内容请参见:

NDK Guides >>

三、总结

JNI 的内容涉及众多,比如 Java 数据类型与 JNI 数据类型之间的对应关系、JNI 类型签名、JNI 与 Java 对象互操作等。

想了解更多关于 JNI 的知识,建议查阅官方文档:

JNI Specification >>
JNI Types and Data Structures >>
JNI Functions >>

本文由 Fynn_ 原创,未经许可,不得转载!

推荐阅读更多精彩内容