我找不到任何关于JNI如何在Android上运行的详细解释的详细说明,所以:
由于每个Android应用程序都在自己的进程中运行,并且有自己的Dalvik / ART虚拟机实例,我认为本机代码将在同一个进程中执行,对吗?
我读到当VM调用一个函数时,它传递一个JNIEnv指针,一个jobject指针和Java方法声明的任何Java参数。 但这是如何在装配层面(引擎盖下)制作的?
我读到你可以使用JNIEnv提供的函数实例化对象,调用方法等,比如Reflection。因此,我的问题是:我是否对VM进行“直接”内存访问,或者我总是使用JNIEnv的函数?
答案 0 :(得分:1)
Android JVM在Apache许可下,因此可以以源代码的形式找到最详细和准确的描述。请注意,有两种不同的JVM:dalvik和art。在引擎盖下它们是非常不同的,只要JNI的用户可以考虑特殊的改编。
本机代码将在同一进程中执行
完全。请注意,Android应用程序可以在多个进程中运行,也可以生成子进程(正常的Unix行为)。但JNI不是IPC。
这是如何在装配级别进行的?
或多或少,这是相关的描述 问题:What does a JVM have to do when calling a native method?
我是"直接"内存访问VM?
是的,你有。您的C代码和JVM之间没有安全屏障。您可以对数据结构进行反向工程,并执行您喜欢的任何操作。 JVM的确切实现不仅取决于Android版本,而且可以在没有通知的情况下进行修改,只要JVM的公共API(包括JNI)兼容即可。您可以通过直接内存访问JVM来做一些有用的事情是很少的,但它会崩溃的风险非常高。
请注意,这不是安全问题:您的C代码在单独的进程(使用Java代码)中运行,并且受到与Java代码相同的权限限制。它无法访问其他应用程序或procsses的私有内存。无论您在JVM实例中更改什么都不会影响运行其他应用程序的VM。