JNI系列一 项目搭建

2023年 10月 7日 90.6k 0

本文是JNI入门阶级的文章,介绍JNI开发的流程,如何快速在项目中集成JNI,记录方便后续查阅。

文本将实现使用JNI输出"Hello World"的字符串,并将其显示出来

配置JNI环境

在app/src/main下新建cpp文件夹,新建native_lib.cpp文件,内容暂时为空

1696663004912_capture_image.jpeg

有了C/C++源码文件之后,需要指定这个源文件所在的路径。

cpp目录下新建一个CMakeLists.txt文件,内容如下

cmake_minimum_required(VERSION 3.4.1)

# add_library用于创建一个库,并定义源文件的位置以及库的名字
add_library(
# 定义库的名字
nativeapplication
# SHARED表示将这个库设置为共享库
SHARED
# 设置源文件的路径
src/main/cpp/native_lib.cpp)

在build.gradle文件中告诉Gradle CmakeLists.txt所在的路径

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

加载so库

接下来在Java代码中定义native方法,首先我们需要加载我们定义的native库,并定义native方法

// MainActivity.java
public class MainActivity extends AppCompatActivity {
    static {
        // 用于加载so库
        System.loadLibrary("nativeapplication");
    }
    
    public native String stringFromJNI();
}

实现JNI方法

我们回到C语言文件,输入stringFromJNI,这个时候编译器会提示自动补全JNI方法,生成的方法如下

// extern "C":实现C++和C的混合编程,告诉C++编译器按照C的链接方式进行链接,在cpp文件中需要加这个定义,c文件则不需要
// JNIEXPORT:JNI的一个宏定义,表示该函数是可见的,其主要目的是为了让Java可以找到这个函数,相当于定义了函数可见性。
// jstring:函数返回类型,对应Java中的String
// JNICALL:宏定义,在Linux平台上是一个空定义
// 函数名: Java_包名_类名_方法名
// JNIEnv* env:JNIEnv包含一些常用的JNI方法,如创建Java对象,调用Java对象的方法等
// jobject:是一个指针,指向调用该native方法的Java对象,注意这里只有参数类型,省略了参数名(C++是可以省略参数名的)
#include 
#include 

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_nativeapplicationtest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    
}

然后我们实现这个C++方法

// native_lib.cpp
// 用到了C++ std库的string,C是没有string的
std::string hello = "Hello from C++";
// NewStringUTF返回jstring类型,对应Java中的String,
return env->NewStringUTF(hello.c_str());

最后我们在Activity中显示这个字符串

TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());

点击运行即可在屏幕上看到"Hello from C++"

实际上这个工程就是在Android Studio使用Native C++模板创建的原始工程

编译之后生成的so文件位于
build>intermediates>cmake>debug>obj目录下

后记

与技术无关,记录一下个人的想法

说一下写这篇文章的动机吧,因为这篇文章看上去很简单,掘金上也有很多类似的文章了,为什么还要写呢,因为想积累一点自己的东西。

工作两年,在掘金上走马观花看了很多篇文章,有代码的照着敲一遍,没代码的粗略看一遍,浅尝辄止,看完就扔在一边,最后就是什么都知道,但是什么都不会。

想着写点文章,也算是自己学习和工作的证明了,可是总觉得自己要写的东西已经有很多类似的,写出来没什么技术含量,不过这世界上水文那么多,也不差我这一篇,重要的是写作时对知识的理解,和分享知识的过程。

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论