2012-03-05 13 views
2

JNIを介してC++コードを呼び出してブロック操作を開始するAndroid/Javaアプリケーションがあります。 C++コードはこのブロック操作を行うためにスレッドを開始し、終了するとJNIをコールバックする必要があります。pthreadからオブジェクトを初期化するときに "NoSuchMethodError"が発生する

C++への呼び出しは問題なく動作します。しかし、JNIに電話をかけると、さまざまなエラーが報告されています。

新しいスレッドからjclass参照を取得することは明らかに法的ではありません。私は、Javaコードにコールバックしようとしているこれらのスレッドの1で

static jclass sampleClazz; 

jint JNI_OnLoad(JavaVM *vm, void *reserved) 
{ 
    jvm = vm; 

    JNIEnv* env = NULL; 
    jint result = jvm->GetEnv((void**)&env, JNI_VERSION_1_6); 

    if(env == NULL) { __android_log_print(ANDROID_LOG_DEBUG, "JNI_OnLoad", "NULL");} 

    sampleClazz= env->FindClass("com/sample/SampleClazz"); 
    sampleClazz= (jclass) env->NewGlobalRef(sampleClazz); 

    ...etc... 
} 

:そのアクションを実行するので、すべてのクラスのルックアップのはJNI_OnLoad()方法で行われ、このように見えるされている「予期しない動作」を与えます。コールバックメソッドは、次のようになります。

void cCallBackOne() { 
    JNIEnv* env; 
    jvm->AttachCurrentThreadAsDaemon(&env, NULL); 

    jmethodID init = env->GetMethodID(sampleClazz, "<init>", "()V"); 
    if(init == NULL) { 
     __android_log_print(ANDROID_LOG_DEBUG, "START", "NULL HERE"); 
    } else { 
     __android_log_print(ANDROID_LOG_DEBUG, "START", "ALL FINE"); 
    } 

残念ながらいくつかの未知の理由でこのログインしている/投げ:

Exception Ljava/lang/NoSuchMethodError; thrown while initializing Lcom/sample/SampleClazz; 
NULL HERE 

異なるソリューションの私がするためにJNI_OnLoad方法にGetMethodIdを移動しようとしたての作業中元のJavaスレッドからメソッド参照を正しく引き出すことができるかどうかを確認してください。それはうまく動作します...しかし、私はこれを行うと、不思議なことですコールバック内のコードも動作し始めます

私は大規模に困惑しています。私は何が起こっているのか分かりませんし、次に何を試していいのか分かりません。

+0

ブロックされていても、スレッドを開始する理由は何ですか?あなたは同じスレッドで仕事をすることができるように聞こえる... –

+0

Javaでスレッドを作成しようとしましたか?それは私が操作をブロックするために行うもので、正常に動作します。それで、問題のあるCからJavaへのコールバック・メカニズムを混乱させる必要はありません。 – BitBank

+0

私は正当な理由で私がやっていることを確認することができます。 – Graeme

答えて

0

これまでのところ、私はそれを他の場所に投げ込まれたエラーに置いており、これはちょうどそのような問題の症状です。私は、メソッドのこれらのセットを作成しているし、今私の呼び出しの各後check()を使用しています。ただ、これらのチェックを追加すること

void check(jclass toCheck) { 
    if(toCheck == NULL) { 
     __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jclass"); 
    } 
} 

void check(jmethodID toCheck) { 
    if(toCheck == NULL) { 
     __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jmethodID"); 
    } 
} 

void check(jfieldID toCheck) { 
    if(toCheck == NULL) { 
     __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jfieldID"); 
    } 
} 

void check(jobject toCheck) { 
    if(toCheck == NULL) { 
     __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jobject"); 
    } 
} 

は、これまでのところ、私は他の理由があると思います正気のために...私の問題を解決しましたなぜかこれがどういう意味なのかを説明するのに "魔法"よりも...

コード実行の早い段階でスローされた奇妙な例外があったことを認めなければならないのですが、これは以前のクラッシュ。

レッスン:あなたのコードの人を守ることを忘れないでください! JNIがクラッシュした場合、それ自体が保持され、道のりの何かが破損することになります。

0

私はこれが古くから知っていましたが、私はちょうど同じ問題を抱えていました。 JavaクラスがJavaコードで使用されていないことが判明したため、最適化されました。私は私のアプリでJavaクラスを使用し、それはすべてのCの側面から動作します。

関連する問題