从独立本机代码调用java代码

从独立本机代码调用java代码,java,android,c++,android-ndk,dalvik,Java,Android,C++,Android Ndk,Dalvik,在android操作系统中,我想从独立代码调用用户定义的java类API i、 e.如果有一个类“HelloWorldActivity”具有“getint”API。我想从本机应用程序中将其称为“nativecaller” 我发现这篇文章与此相关,但我不清楚是如何实现的。 下面是代码片段: #include <jni.h> #include <cutils/log.h> #include <stdlib.h> int main(){ JavaVM *

在android操作系统中,我想从独立代码调用用户定义的java类API

i、 e.如果有一个类“HelloWorldActivity”具有“getint”API。我想从本机应用程序中将其称为“nativecaller”

我发现这篇文章与此相关,但我不清楚是如何实现的。

下面是代码片段:

#include <jni.h> 
#include <cutils/log.h>
#include <stdlib.h>
int main(){
    JavaVM *jvm;
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options[1];
   options[0].optionString = "-Djava.class.path=/data/";
   vm_args.version = JNI_VERSION_1_6;
   vm_args.options = options;
   vm_args.nOptions = 1;    
   vm_args.ignoreUnrecognized = JNI_FALSE;

   /* Create the Java VM */    
   int res = JNI_CreateJavaVM(&jvm, &env, &vm_args); 

   if(!res){    
           /* invoke the Main.test method using the JNI */    
           jclass cls = env->FindClass("com/abc/mypackage/HelloWorld"); //it is not able to find the class

        if(!cls)LOGE("\n\n\nclass not found!!!");    
         else{
           jmethodID mid = env->GetMethodID(cls, "getint", "(V)I");    
           env->CallStaticVoidMethod(cls, mid,10);    
           }

           /* We are done. */    
           jvm->DestroyJavaVM();

    }
   else    
   LOGE("\n\n\n\n CreateJAVAVM failed!!");      
}
#包括
#包括
#包括
int main(){
JavaVM*jvm;
JNIEnv*env;
JavaVMInitArgs vm_args;
JavaVMOption选项[1];
选项[0]。选项字符串=“-Djava.class.path=/data/”;
vm_args.version=JNI_version_1_6;
vm_args.options=选项;
vm_args.nOptions=1;
vm_args.ignoreunrecogned=JNI_FALSE;
/*创建Java虚拟机*/
int res=JNI_CreateJavaVM(&jvm,&env,&vm_args);
如果(!res){
/*使用JNI*调用Main.test方法
jclass cls=env->FindClass(“com/abc/mypackage/HelloWorld”);//它无法找到该类
如果(!cls)LOGE(“\n\n\n未找到类!!!”;
否则{
jmethodID mid=env->GetMethodID(cls,“getint”,V)I);
env->CallStaticVoidMethod(cls,mid,10);
}
/*我们完成了。*/
jvm->javavm();
}
其他的
LOGE(“\n\n\n\n CreateJAVAVM失败!!”;
}
FindClass
正在返回
null

1.是否可以访问活动内的类(apk)

2.-Djava.class.path应该指向什么


欢迎您的任何意见

Dalvik提供了一个名为
dalvikvm
的命令,该命令与您尝试执行的操作没有太大距离。它只是
libdvm.so
(请尝试
adb shell dalvikvm-help
)的命令行包装。您可以看到源代码

尝试一个快速测试:不要查找您的应用程序类,而是查找您知道将存在的内容(例如,
java/lang/String
)。这将告诉您VM是否能够做任何事情

在设备上,
BOOTCLASSPATH
将已在您的环境中配置(
adb shell printenv BOOTCLASSPATH
),但
CLASSPATH
不会。将
CLASSPATH
环境变量设置为以冒号分隔的.jar或.apk文件列表,而不是目录列表

您需要以root用户身份运行,以便您的命令行应用程序有权在
/data/dalvik cache
中为APK创建条目。(如果这样的条目已经存在,您可能不需要是root。)


如果出现问题,请检查logcat输出以了解详细信息。

类路径是指向.class文件的路径。请参阅:是的,但在我的例子中,我引用的类位于apk内部,即classes.dex。所以这里有点不知所措!!我猜您不能在独立的本机工具中使用apk中的类。这听起来也没什么用处,因为apk/应用程序不会运行,所以您试图调用的任何方法都不会返回有用的数据。如果要在正在运行的应用程序中使用本机代码,则必须使用标准NDK方法,从具有现有JVM的正在运行的应用程序中执行本机代码。@zapl-事实并非如此。apk只是一个特殊的jar(包含dex而不是java类),但是在某些Android版本上,文件本身可能无法被外国用户ID读取。fadden还指出了缓存可能存在的权限问题,但如果从零开始,则有解决方法。@ChrisStratton是的,apk是一种带有.dex而不是类的jar。但是apk当然不可通过root访问,我认为这里的目的是在
HelloWorldActivity
的现有实例上调用一些方法,而生成一个新的dalvik实例是不可行的。