Android 开创java世界(JNI Invocation API)

在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/来代替了。

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$

 

posted @ 2019-03-27 10:08  星辰之力  阅读(464)  评论(0编辑  收藏  举报