Android JNI 技术指南:入门 JNI 工程详解
2024-01-03 15:49:52
深入探究 Android Java 原生接口 (JNI) 的细节
前言
在移动应用程序开发的世界中,Android Java 原生接口 (JNI) 扮演着不可或缺的角色。它赋予开发人员利用原生代码强大功能的能力,从而显著提升应用程序的性能和效率。本博客将带你深入了解 JNI 的运作原理,一步步构建一个 JNI 工程,并深入分析其关键细节。
JNI 工程结构
一个典型的 JNI 工程包含以下主要文件:
- Java 代码(.java): 负责与原生代码交互的 Java 代码。
- C/C++ 代码(.c/.cpp): 原生代码,包含应用程序的业务逻辑。
- Android.mk: 用于构建原生代码的 Makefile。
- Application.mk: 用于配置和管理整个工程的 Makefile。
编写 Java 代码
Java 代码负责加载原生库并与之交互。首先,我们需要包含必要的头文件并声明一个原生方法,该方法将调用原生代码中的函数:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
// Declare the native method
public native String getNativeString();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Load the native library
System.loadLibrary("native-lib");
// Call the native method
TextView textView = findViewById(R.id.text_view);
textView.setText(getNativeString());
}
}
编写 C/C++ 代码
C/C++ 代码包含要从 Java 代码调用的实际业务逻辑。使用 extern "C" 指定符,以允许 Java 代码访问原生函数:
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_native_MainActivity_getNativeString(JNIEnv *env, jobject instance) {
std::string hello = "Hello from JNI!";
return env->NewStringUTF(hello.c_str());
}
构建和运行工程
要构建工程,请运行以下命令:
ndk-build
如果构建成功,使用以下命令运行应用程序:
adb install -r app/build/outputs/apk/debug/app-debug.apk
JNI 工程细节分析
1. extern "C"
extern "C" 指定符告知编译器将函数声明为 C 函数,以便 Java 代码可以访问它。这是因为 Java 使用 Java 名称规范,而 C/C++ 使用 C++ 名称规范。
2. 动态库加载
System.loadLibrary() 方法用于加载原生库。它接受一个字符串参数,表示要加载的库的名称。在本例中,我们加载了名为 "native-lib" 的库。
3. 原生方法调用
getNativeString() 方法是 JNIEXPORT 修饰的,该修饰符指定该方法可从 Java 代码导出。它接受两个参数:JNIEnv* 和 jobject,并返回一个 jstring,其中包含要返回的字符串。
结论
本博客深入探讨了 Android JNI 工程的细节,包括 JNI 工程结构、Java 和 C/C++ 代码编写以及构建和运行工程。通过理解这些细节,你可以构建高效、强大的 JNI 应用程序,充分利用原生代码的优势。在后续的文章中,我们将进一步探索 JNI 的高级特性,例如数据类型映射、异常处理和线程管理。
常见问题解答
-
什么是 JNI?
JNI 是 Android Java 原生接口,它允许 Java 代码与原生代码交互。 -
为什么使用 JNI?
JNI 可用于提高应用程序的性能、访问特定于平台的功能或集成外部库。 -
如何编写 JNI 代码?
需要编写 Java 代码以加载原生库和调用原生方法,并编写 C/C++ 代码以实现这些原生方法。 -
如何构建和运行 JNI 工程?
使用 ndk-build 命令构建工程,并使用 adb install 命令运行应用程序。 -
extern "C" 有什么作用?
extern "C" 指定符确保原生函数可以从 Java 代码访问。