在Android的世界中,由名称为app_process的C++本地应用程序(路径为:framework/base/cmds/app_process/app_main.cpp)调用JNI Invocation API 在自身进程中加载dalvikvm虚拟机,这样就开创了java世界.
现在就简单的Demo一下这个原理,在Ubuntu11.10的终端中操作,已安装了jdk的条件。
1.首先创建一个工作目录:
mkdir javaVMTest
2.创建一个java文件,Called.java,内容:
public class Called { public static void main(String[] args) { // 把参数打印出来 System.out.println(args[0]); } }
3.编译这个java文件为class文件:
javac Called;
生成的Called.class就在当前目录下。
4.编写本地的C/C++程序,此处以C为例,名字为:invocationApi.c
#include <jni.h> /* where everything is defined */ int main() { JavaVM *vm; /* denotes a Java VM */ JNIEnv *env; /* pointer to native method interface */ JavaVMInitArgs vm_args; /* JDK 6 VM initialization arguments */ JavaVMOption* options = new JavaVMOption[1]; //options[0].optionString = "-Djava.class.path=/usr/lib/java"; options[0].optionString = "-Djava.class.path=/home/joy/android4.0.3/external/javaVMTest"; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = 1; vm_args.options = options; vm_args.ignoreUnrecognized = false; /* load and initialize a Java VM, return a JNI interface * pointer in env */ JNI_CreateJavaVM(&vm, (void**)&env, &vm_args); //delete options; jclass cls = (*env).FindClass("Called"); //printf("%p %d %d\n",cls,size,a); printf("%p \n",cls); jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); jstring jstr = env->NewStringUTF("Hello JNI Invocation API !!!"); jclass stringClass = env->FindClass("java/lang/String"); jobjectArray args = env->NewObjectArray(1,stringClass,jstr); env->CallStaticVoidMethod(cls, mid, args); /* We are done. */ vm->DestroyJavaVM(); return 0; }
5.编译这个c文件,先要找到jdk的位置:
which javac;
这样jdk的位置就能找到了,一般都在/usr/lib/jvm下
这里就用/usr/lib/jvm/java-6-sun-1.6.0.16/来代替了。实际我的是31,呵呵。
6.找到libjvm.so这个东东是关键。
一般都在jdk路径下面的:/jre/lib/amd64/server或者是什么i386等等的,
用find -name "libjvm.so"能很快找到。
7.配置编译时连接库:
在当前终端中,执行:
export LD_LIBRARY_PATH=/usr/lib/jvm/java-6-sun-1.6.0.16
/jre/lib/amd64/server
8.执行编译命令:
g++ -I /usr/lib/jvm/java-6-sun-1.6.0.16
/include -I /usr/lib/jvm/java-6-sun-1.6.0.16
/include/linux -ljvm -L/usr/lib/jvm/java-6-sun-1.6.0.16
/jre/lib/amd64/server invocationApi.c
9.运行结果:
运行编译出的a.out:
./a.out
如果正常情况下结果为:
joy@joy-top:~/android4.0.3/external/javaVMTest$ ./a.out
Hello JNI Invocation API !!!
joy@joy-top:~/android4.0.3/external/javaVMTest$
10.恭喜你,刚刚创造了一个java世界!
相关推荐
world 文档,描述了Android g1环境,C、Java、JNI调用(C调Java、Java调C)基本运算、方法调用、字符串连接的效率测试结果。
Android NDK 开发时需要的 常用的JNI API
JNI开发中使用的API文档,此文档为CHM格式,非PDF格式
android JNI C 调用Java
完整的展示了Java调用C++ API/dll示例程序. 说明如下: 1. mrSocketAPICInt是准备被java调用的API 2. mrSocketAPIJavaInt是java调用C++ api的中间层 3. mrSocketAPIJavaIntDemo是java程序,展示与C++ api如何对接。...
JAVA使用JNI读写INI文件的实例。 JAVA本身并没有读写INI文件的现成方法,有些人自己编写方法来读写INI文件,但是这样的方法或多或少的存在着一些问题。...通过此例子程序再进行推敲就可以对JAVA用JNI调用API的功能。
Java的JNI相关方面的书籍,很好,推荐下载
android_stduio_serial_jni_api
jni封装串口通讯例子源码,在jni层封装rs232,在android用java调用实现控制 串口发送和接收数据
Android Java代码与JNI交互 JNI访问Java类方法 (七)
Android Java代码与JNI交互 JNI方法Java类字段 (六)
Android Java代码与JNI交互 JNI访问Java构造方法(九).zip
android jni native C++访问java层数组,java类对象属性和方法,回调接口和线程回调接口 内附可以正常使用的demo
Java通过JNI调用DLL动态库,亲测试编写
完整的实现java跨平台调用C程序源码,包含JAVA源码和C源码以及编译后的demo dll。将dll放到jdk bin目录下,java 项目可以直接运行。若要修改dll可以,修改C源码后重新编译生成dll。该demo处理了多线程调用c,全局...
Android Java_JNI_Native
鉴于本站中的jniAPIchm版不能打开的问题,反编译出的html版
通过JNI接口静态注册的native方法去创建线程,同时提供native回调Java的方法。通过这个框架可以去实现线程监听某一个状态,然后回调Java的方法(如发消息去通知顶层,实现显示)
Java通过JNI调用算法的一些坑