(六)Android Studio 使用 JNI

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。

一、C/C++ 到二进制文件

对于 CPU 来说,只能识别 0101 这样的二进制,所以我们编写的 C/C++ 文件需要进行一系列的处理,转化为二进制文件,从而可以被 CPU 识别到。这中间主要分为 预处理–>编译–>汇编–>链接 四个步骤。

1.预处理:读取 C/C++ 文件,对其中的伪指令进行处理( 以# 开头的指令)和特殊符号进行处理。伪指令包括宏定义指令、条件编译指令、头文件包含指令等。

2.编译:编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。

3.汇编:把编译时候生成的汇编代码整理成目标文件,但是此时目标文件还是不可执行的。 Window 环境下是以 .obj 结尾的文件, Linux 环境下是以 .o 结尾。

4.链接:把目标代码和二进制的库文件以及其它内容合并成最终的可执行文件,Window 下有可执行文件 .exe、库文件 .dll等, Linux 下对应的库文件是 .so 结尾的文件。

将 C/C++ 文件编译链接生成二进制文件,这个过程是由编译器进行实现,Eclipse 和 Android Studio 采用不同的编译器进行编译,他们采用的编译规则也有所不同。

Eclipse :采用 GUN 编译器,编译规则存放在 Android.mk 文件,包括需要编译哪些文件、需要链接的动态库、生成的 .so 库的名字等。

Android Studio:采用的是 LLVM 编译器,编译规则是存放在 CMakeList.txt 文件( CMakeList.txt 与 Android.mk 写法不一样)。

二、创建 JNI 项目

1.创建项目

在 Android Studio 中创建 JNI 项目是比较简单的,新建项目的时候勾选 include C++ Support 即可。

这里写图片描述

在这一步把这两个勾选上,Android Studio 会提供一个 C/C++ 异常处理的支持。

这里写图片描述

点击结束,生成项目即可。

异常:

这里写图片描述

如果出现 Error:Unable to get the CMake version located 错误,是没安装 CMake 的原因,打开sdk mananger –> sdk tool, 下载 CMake 。

项目结构:

这里写图片描述

在 main 下的 cpp文件家中,会默认生产一个 .cpp 文件。下方还有一个 CMakeLists.txt 编译规则文件。

2.创建 java 声明文件

创建 java 声明文件 JNITest.java,并在里面声明一个 jni 方法。

JNITest.java

public class JNITest {
    static {
        System.loadLibrary("native-lib");
    }
    public static native String getString();
}

这时候 getString() 会报错,在 Android Studio 中,直接使用 Alt + Enter 可以解决,会帮我们生成对应的 C/C++ 方法,但是没有 .h 头文件,这样也是可以的。

这边不建议直接生成 C/C++ 方法,最好还是先生成 .h 头文件,再进行创建 C/C++ 方法。

3.生成头文件

在 Android Studio 中打开命令行窗口,切换到 \app\src\main\java 目录,用 javah 包名+类名 命令进行生成头文件。

这里写图片描述

运行成功后,在 \app\src\main\java 目录下生成对应的 .h 头文件。
这里写图片描述

4.实现 JNI

把生成的头文件拷贝到 cpp 文件夹下。

这里写图片描述

修改 native-lib.cpp,实现定义的方法。

native-lib.cpp:

#include <jni.h>
#include <string>
#include "com_xiaoyue_jnidemo_JNITest.h"
#include <android/log.h>

#define TAG "JNITest"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)


extern "C"

JNIEXPORT jstring JNICALL Java_com_xiaoyue_jnidemo_JNITest_getString
        (JNIEnv *env, jclass jclz){
    LOGI("JNI test");

    return env->NewStringUTF("JNI test return");
}
#include <android/log.h> 这是安卓提供的一个库,可以允许 C/C++ 代码的日志打印在安卓控制台上。

5.效果

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(JNITest.getString());
    }
}

效果:

在控制台上打印出了 C/C++ 日志。

这里写图片描述

获取到 C/C++ 返回的字符串。

这里写图片描述

到这,一个简单的 JNI 调用完成了。

猜你喜欢

转载自blog.csdn.net/qq_18983205/article/details/79024087