Android JNI介绍(一)- 第一个Android JNI工程

5,114 阅读3分钟

本系列文章列表:

Android JNI介绍(一)- 第一个Android JNI工程

Android JNI介绍(二)- 第一个JNI工程的详细分析

Android JNI介绍(三)- Java和Native的互相调用

Android JNI介绍(四)- 异常的处理

Android JNI介绍(五)- 函数的注册

Android JNI介绍(六)- 依赖其他库

Android JNI介绍(七)- 引用的管理

Android JNI介绍(八)- CMakeLists的使用

一、简述

在平时的开发过程中,大多数人可能没有JNI方面的需求,因此JNI方面的工程配置、如何开始也都不太了解,而网上对此方面的介绍也比较少。因此,本系列文章将从一个新手的角度开始,介绍JNI编程。

二、NDK简介

Android NDK 是一套允许您使用 C 和 C++ 等语言,以原生代码实现部分应用的工具集。在开发某些类型的应用时,这有助于您重复使用以这些语言编写的代码库。

三、JNI简介

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为Java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

四、Android Studio创建简单的JNI工程

在创建Android Project时,在创建的首页中勾选Include C++ support选项即可创建一个模板的hello world程序,可直接运行。相比于普通的Android工程,勾选该项后的工程有以下不同:

工程目录

gradle配置

可以看到,多出了一个native-lib.cpp(C++代码)文件和一个CMakeLists.txt(C++相关配置)文件,app模块下的build.gradle文件也添加了相关配置。

在该默认工程中,我们可以看到一些相关代码:

CMakeLists内容:

# 声明最低的cmake版本
cmake_minimum_required(VERSION 3.4.1)
# 添加一个名称叫native-lib的动态库,该库的源文件为src/main/native-lib.cpp
add_library( native-lib # 库的名称
             SHARED # SHARED:动态库、STATIC:静态库
             src/main/native-lib.cpp # 源文件,可以是多个
             )
             
# 寻找系统中的log库,保存在log-lib变量中
find_library( log-lib 
              log )
              
# native-lib这个库会去依赖log-lib这个库
target_link_libraries( native-lib
                       ${log-lib} )

Java中加载本地库,并且定义native方法:

    // 加载的library名称,注意:不是C++文件的名称
    static {
        System.loadLibrary("native-lib");
    }
    /**
     * java中定义方法的名称,会根据包名、类名、参数、返回值类型寻找对应的C++方法
     */
    public native String stringFromJNI();

C++中定义好对应的方法:

//对应于java中的stringFromJNI方法
extern "C" JNIEXPORT jstring JNICALL Java_com_wsy_jnitest_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

这样即可实现C++向Java传递一个String。其中的映射规则会在后面进行介绍。

五、工程中的各个文件的关系的梳理

build.gradle:总配置文件,在其中指定CMakeLists.txt的路径;
CMakeLists.txt:native代码的配置,包括和其他库的依赖配置、工程库编译出的结果(静态库、动态库、可执行文件)等;
主C++文件:native代码的实现;

以上就是一个简单的JNI操作,实际的开发过程中不可能仅仅只是这么简单的一个操作,后面会对一些具体操作进行介绍。包括CMakeLists、Java和C++的互相调用、异常处理等。