`
dingran
  • 浏览: 371668 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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/来代替了。实际我的是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世界!

 

 

 

0
0
分享到:
评论
2 楼 yzyspy 2012-10-09  
不错不错!虽然很简单,但是做起来还是会遇到很多苦难的
1 楼 ITboss 2012-10-09  

相关推荐

Global site tag (gtag.js) - Google Analytics