无法从调用Java代码的本机代码获取类引用

时间:2014-06-30 12:19:13

标签: java c++ java-native-interface

我是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

最诚挚的问候 库马尔

2 个答案:

答案 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类编译成类文件,以便本机库可以引用它。