我是Java编程的新手。我试图使用JNI从Native C ++代码调用Java API。我收到以下错误 "无法获得课程参考" 以下是代码段 Java Side:
package com.example.playaudio;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private MediaPlayer mp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
Button button1=(Button)findViewById(R.id.button_1);
Button button2=(Button)findViewById(R.id.button_2);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
}
public void onClick(View v) {
int resId;
switch (v.getId()) {
case R.id.button_1:
resId = R.raw.a;
break;
case R.id.button_2:
resId = R.raw.b;
break;
default:
resId = R.raw.a;
break;
}
// Release any resources from previous MediaPlayer
if (mp != null) {
mp.release();
}
// Create a new MediaPlayer to play this sound
mp = MediaPlayer.create(this, resId);
mp.start();
}
public void onStart() {
int resId;
// Release any resources from previous MediaPlayer
if (mp != null) {
mp.release();
}
resId = R.raw.b;
// Create a new MediaPlayer to play this sound
mp = MediaPlayer.create(this, resId);
mp.start();
}
}
Native Side(带有JNI的C ++):
JavaVM * create_vm() {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption *options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
// Load and Initailize JVM, returns an JNI Intterface
int ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (ret < 0 )
printf("Unable to launch JVM \n");
return jvm;
}
void PlayAudio()
{
int status;
bool isAttached = false;
JNIEnv *env;
printf("PlayAudio\n");
status = gJavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);
status = gJavaVM->AttachCurrentThread((void **)&env, NULL);
jclass interfaceClass =
env->FindClass("com/example/playaudio/MainActivity");
if(!interfaceClass) {
printf("PlayAudio: Failed To Get Class Reference\n");
return;
}
jmethodID altmethod = env->GetMethodID(interfaceClass, "<init>","()V");
jobject obj = env->NewGlobalRef(env->NewObject(interfaceClass, altmethod));
jmethodID method = env->GetMethodID(interfaceClass, "onStart", "(I)V");
if(!method)
{
printf("PlayAudio: Failed To Get Object Method\n");
return;
}
env->CallVoidMethod(obj, method, NULL);
}
如果我的编码有任何问题,请纠正我。以下是错误
PlayAudio
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/playaudio/MainActivity
Caused by: java.lang.ClassNotFoundException: com.example.playaudio.MainActivity
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
PlayAudio: Failed To Get Class Reference
最诚挚的问候 库马尔
答案 0 :(得分:0)
将您的查找类代码放在JNI_OnLoad中,看看它是否有效。如果是这样,那么你就遇到了java类加载器的问题。如果没有,则在运行应用程序时会破坏java类路径。
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
jclass interfaceClass = env->FindClass("com/example/playaudio/MainActivity");
if(!interfaceClass) {
printf("PlayAudio: Failed To Get Class Reference\n");
}
如果你的问题是类加载器,那可能是由于JNLP ......我没有确切地研究为什么问题存在但是我怀疑它与类加载器有关,它具有额外的安全性而没有被解决。这一点都是推测性的,所以请运行上面的测试,让我们知道会发生什么。
答案 1 :(得分:0)
您可以尝试第一步是在选项值上给出Java类的修复路径: options [0] .optionString =&#34; -Djava.class.path =。&#34 ;; ==&GT;改为设置Java库的完整路径 如果它不起作用,我怀疑您将Java方法暴露给本机库的步骤。请仔细检查是否将java类编译成类文件,以便本机库可以引用它。