Android源码学习之如何创建使用JNI
在Android平台下,JNI就是一座Java世界和Native世界之间的桥梁。因此要学好Android的源码,首先就要懂得什么是JNI,如何使用JNI。
JNI是Java Native Interface的缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。下面通过实现简单的加法函数,来手动实现如何使用JNI。
JNI(Java Native Interface)的实现步骤:
- 编写带有native声明的方法的java类。
- 使用javac命令编译所编写的java类。
- 使用javah -jni java类名生成扩展名为h的头文件。
- 使用C/C++(或者其他编程想语言)实现本地方法。
- 将C/C++编写的文件生成动态连接库。
1. 编写Java程序。
public class NativeTest { public static void main(String[] args) { NativeTest aTest = new NativeTest(); int i0 = Integer.valueOf(args[0]).intValue(); int i1 = Integer.valueOf(args[1]).intValue(); double d = aTest.Add(i0, i1); System.out.println("i0 + i1 = " + d); } public native double Add(int i, int j); static { System.loadLibrary("NativeTest"); } }
在Java的文件中,首先声明一个Native方法public native double Add(int i, int j);
注:在该方法中不包含任何代码(具体代码在C++语言或者其他语言中实现,并且作为DLL提供)。
为了确保Java虚拟机在首次使用该类的时候将DLL装载到内存,需要在包含这个Native方法的类中使用静态初始化程序块。如:
static { //装载动态链接库 System.loadLibrary("NativeTest"); }
2. 在doc下,使用javac NativeTest.java 命令编译java类文件。
3. 在同样的文件目录下,使用javah -jni NativeTest 命令生成NativeTest.h文件,生成的文件内容如下所示。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class NativeTest */ #ifndef _Included_NativeTest #define _Included_NativeTest #ifdef __cplusplus extern "C" { #endif /* * Class: NativeTest * Method: Add * Signature: (II)D */ JNIEXPORT jdouble JNICALL Java_NativeTest_Add (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
4. 使用C/C++(或者其他编程想语言)实现NativeTest.h头文件的方法,也就是java文件中没实现的需要通过动态链接库调用的Add方法。其中在相同的目录中建立NatieTest.cpp实现文件,程序为:
#include "NativeTest.h" #include <math.h> JNIEXPORT jdouble JNICALL Java_NativeTest_Add (JNIEnv *env, jobject obj, jint i, jint j) { return i + j; }
实现Add函数。
5. 使用vc++ 的cl命令进行编译cpp文件,生成dll库文件,供java调用实现。
由于我的电脑安装的vs2012,所以可以通过VS2012开发人员命令提示,输入cl命令,编译。
首先cd到NativeTest程序目录下,输入:cl -I "C:\Program Files\Java\jdk1.7.0_07\include" -I "C:\Program Files\Java\jdk1.7.0_07\include\win32" -LD NativeTest.c -FeNativeTest.dll
其中C:\Program Files\Java\jdk1.7.0_07\include是我本地安装的jdk路径,输入时一定要加“”。最后会生成NativeTest.exp NativeTest.dll等文件。
6. 最后运行java程序,java NativeTest 1 2 结果如下所示:
这就表示我们手动建立的JNI成功。
对JNI有了初步的了解,下一步就可以更好的理解Android源码了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构