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$

原文地址:https://www.cnblogs.com/zhujiabin/p/10605593.html

时间: 2024-08-01 18:18:13

Android 开创java世界(JNI Invocation API)的相关文章

Android JNI 学习(十一):Invocation Api

1. 简介 Invocation API允许软件提供商在原生程序中内嵌Java虚拟机.因此可以不需要链接任何Java虚拟机代码来提供Java-enabled的应用程序. 以下代码演示如何使用: #include <jni.h> /* where everything is defined */ //... JavaVM *jvm; /* denotes a Java VM */ JNIEnv *env; /* pointer to native method interface */ Java

The Invocation API(转,在C++中调用Java)

转载自:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html Chapter   5 The Invocation API allows software vendors to load the Java VM into an arbitrary native application. Vendors can deliver Java-enabled applications without

JNI学习之Invocation API

本文是对链接http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html的学习笔记,限于英文水平和对JNI的理解,可能存在错误. 简介 通过使用Invocation API,使用C/C++开发的本地应用可以访问Java虚拟机提供的特性.为了描述简单,下面提到的VM指的都是Java虚拟机. 创建VM 在本地应用里,调用JNI_CreateJavaVM()方法可以完成初始化.加载VM,并返回指向新VM对象

使用Cydia Substrate 从Native Hook Android Java世界

这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工程.不需要创建默认的Activity.修改AndroidManifest.xml如下: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.cyd

Android(java)学习笔记257:JNI之NDK开发步骤(helloword案例)

1.下面通过一个HelloWorld案例来说明一下JNI利用NDK开发过程(步骤) 分析:我们在Win7系统下编译的C语言代码,我们知道C语言依赖操作系统,不能跨平台,所以我们要通过NDK工具把在Win7系统下编写的C代码,转化为可以在Linux(Linux2.6.6---Android内核)运行的二进制代码,最后通过JNI协议规范,Android中java代码就可以调用这个转化后的二进制代码运行. (1)在Eclipse中新建一个Android工程,命名为"HelloWorld",如

Android 和Java API的一个坑:SimpleDateFormat

今天上班遇到这么一个意料之外的异常: 出问题的代码是这样的(已去除上下文信息): Log.i(LOG_TAG, new SimpleDateFormat("YYYY-MM-dd HH:mm:ss", Locale.CHINA) .format(System.currentTimeMillis())); 反复检查,感觉没有问题,于是新建一个Java Project,直接输出同样的代码: public class Main{ public static void main(String[]

android框架Java API接口总注释/**@hide*/和internal API

Android有两种类型的API是不能经由SDK访问的 l 第一种是位于com.android.internal包中的API我,位于frameworks/base/core/java/com/android/internal/.我将称之为internal API. l 第二种API类型是一系列被标记为@hide属性的类和方法.从严格意义上来讲,这不是一个单一的API和类,而是一些的被隐藏的API和类,称之为hidden API Internal和hidden API的区别 Hidden API之

Android(java)学习笔记255:JNI之JNI概念

1. JNI是什么? java native interface (java本机接口) 比如方法声明: public final native Class<?>  getClass():   (来自源码Object.java) 上面方法没有方法体,但是它不是抽象方法,它是具体方法,因为它加了native修饰了,说明这个方法是使用底层C实现的. java提供JNI这个接口规范,可以去调用其他程序语言编写的功能模块(不必要利用java重新开发),可以调用C/C++,或者VB等等. 2.  为什么要

[转载] 深入理解Android之Java虚拟机Dalvik

本文转载自: http://blog.csdn.net/innost/article/details/50377905 一.背景 这个选题很大,但并不是一开始就有这么高大上的追求.最初之时,只是源于对Xposed的好奇.Xposed几乎是定制ROM的神器软件技术架构或者说方法了.它到底是怎么实现呢?我本意就是想搞明白Xposed的实现原理,但随着代码研究的深入,我发现如果不了解虚拟机的实现,而仅简单停留在Xposed的调用流程之上,那真是对Xposed最大的不敬了.另外,歪果仁为什么能写出Xpo