質問

well, my app java code as follows:

package doc.android.demo;

public class NativeInterface {


    private String mStrCrtMsg;
    /** The current file name to be displayed */
    private String mStrCrtFileName;
    public static final native int NtvPerformADT(int test, String path);
    public static final native int registerImage(char[] szDarkPlane0, char[] szDarkPlane1, 
            char[] szLightPlane0, char[] szLightPlane1);
    public static final native int getOutPut(char[] szHdrImg);

    /** this method is called from the JNI code */
    public void DisplayMessage(String strMessage) {
        mStrCrtMsg = mStrCrtMsg + "\n" + strMessage;
        System.out.println("huangzhiquan app DisplayMessage" + mStrCrtMsg);

    }

    /** this method is called from the JNI code */
    public void DisplayFileName(String strFileName) {   
        mStrCrtFileName = strFileName;
        System.out.println("huangzhiquan app DisplayFileName" + mStrCrtFileName);

    }
}

and my JNI code is:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "ADT.h"
/* Header for class doc_android_demo_NativeInterface */

#ifndef _Included_doc_android_demo_NativeInterface
#define _Included_doc_android_demo_NativeInterface


#define TRUE 1
#define FALSE 0

#define NULL 0

// Logging support
#if defined(ANDROID) && defined(LOGGING)
#include <android/log.h>
#else
#include <android/log.h>
//#define __android_log_print(...) do{}while(0)
#endif

JNIEnv * theEnv = 0;
jobject * theObj = 0;
jmethodID midDM;
jmethodID midDFN;


/*
 * Class:     doc_android_demo_NativeInterface
 * Method:    NtvPerformADT
 * Signature: (ILjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_doc_android_demo_NativeInterface_NtvPerformADT
  (JNIEnv * env, jobject thiz, jint test, jstring strLibsDirectory){
     theEnv = env;
        theObj = & thiz;

        jclass cls;

        cls = ( * env)->GetObjectClass (env, thiz);
        __android_log_print(ANDROID_LOG_ERROR, "huangzhiquan class name", cls);

        midDM = ( * env)->GetMethodID (env, cls, "DisplayMessage", "(Ljava/lang/String;)V");
        {
            __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", " Can't find method DisplayMessage");
            return 1;
        }

        midDFN = ( * env)->GetMethodID (env, cls, "DisplayFileName", "(Ljava/lang/String;)V");

        if (midDFN == 0)
        {
            __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", "Can't find method DisplayFileName");
            return 1;
        }

        jboolean isCopy;
        const char * pszLibsDir = ( * env)->GetStringUTFChars ( env, strLibsDirectory, & isCopy);
        int retval = PerformADT (test, pszLibsDir);
        // // Free up memory to prevent memory leaks
        ( * env)->ReleaseStringUTFChars (env, strLibsDirectory, pszLibsDir);

        theEnv = 0;
        theObj = 0;
        midDM  = 0;
        midDFN = 0;

        return (jint) retval;
}

/*
 * Class:     doc_android_demo_NativeInterface
 * Method:    registerImage
 * Signature: ([C[C[C[C)I
 */
JNIEXPORT jint JNICALL Java_doc_android_demo_NativeInterface_registerImage
  (JNIEnv * env, jobject thiz, jcharArray darkplane0, jcharArray darkPlane1, jcharArray lightPlane0, jcharArray lightPlane1){
    int retval = 0;
    return (jint) retval;
}

/*
 * Class:     doc_android_demo_NativeInterface
 * Method:    getOutPut
 * Signature: ([C)I
 */
JNIEXPORT jint JNICALL Java_doc_android_demo_NativeInterface_getOutPut
  (JNIEnv * env, jobject thiz, jcharArray hdrout){
    jcharArray charArr;
    return charArr;
}


void Java_DisplayMessage (const char * pszMsg)
{
    jstring strMsg;
    jclass cls;
    JNIEnv * env = theEnv;
    jobject jobj = * theObj;

    strMsg = ( * env)->NewStringUTF (env, pszMsg);

    if ( strMsg != NULL)
    {
        ( * env)->ExceptionClear (env);
        ( * env)->CallVoidMethod (env, jobj, midDM, strMsg);

        if ( ( * env)->ExceptionOccurred (env) )
        {
            __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", "error occured calling DisplayMessage");
            ( * env)->ExceptionDescribe (env);
            ( * env)->ExceptionClear (env);
        }

        ( * env)->DeleteLocalRef (env, strMsg);
    }
    else
        __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", "string could not be allocated");
}
//_____________________________________________________________

void Java_DisplayFileName (const char * pszMsg)
{
    jstring strMsg;
    jclass cls;
    JNIEnv * env = theEnv;
    jobject jobj = * theObj;

    strMsg = ( * env)->NewStringUTF (env, pszMsg);

    if ( strMsg != NULL)
    {
        ( * env)->ExceptionClear (env);
        ( * env)->CallVoidMethod (env, jobj, midDFN, strMsg);

        if ( ( * env)->ExceptionOccurred (env) )
        {
            __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", "error occured calling DisplayFileName");
            ( * env)->ExceptionDescribe (env);
            ( * env)->ExceptionClear (env);
        }

        ( * env)->DeleteLocalRef (env, strMsg);
    }
    else
        __android_log_print (ANDROID_LOG_ERROR, "doc/android/demo", "string could not be allocated");
}

#endif

I don't know why it always report, although I tried my best. Can someone help me?

09-17 18:05:19.848 E/AndroidRuntime( 7736): FATAL EXCEPTION: AndroidDemo thread

09-17 18:05:19.848 E/AndroidRuntime( 7736): java.lang.NoSuchMethodError: no method with name='DisplayMessage' signature='(Ljava/lang/String;)V' in class Ljava/lang/Class;

09-17 18:05:19.848 E/AndroidRuntime( 7736):     at doc.android.demo.NativeInterface.NtvPerformADT(Native Method)

09-17 18:05:19.848 E/AndroidRuntime( 7736):     at doc.android.demo.ADTActivity.PerformADT(ADTActivity.java:81)

09-17 18:05:19.848 E/AndroidRuntime( 7736):     at doc.android.demo.ProcessingThread.run(ProcessingThread.java:36)
役に立ちましたか?

解決

cls = ( * env)->GetObjectClass (env, thiz);

returns the Class class, as indicated by NoSuchMethodError (...) in class Ljava/lang/Class;

This is because your native method is static, therefore there is not jobject to be passed to the native method, but rather a jclass. You signature should be:

JNIEXPORT jint JNICALL Java_doc_android_demo_NativeInterface_NtvPerformADT
   (JNIEnv * env, jclass cls, jint test, jstring strLibsDirectory){

You can then use cls directly.

However, you should notice that being in a static method, there is no object on which to call the method you'll find this way. (DisplayMessage being non static)

他のヒント

I'm not sure what you're trying to do, and I don't see a call to NtvPerformADT which is probably generating the error, but could it have something to do with the function named Java_DisplayMessage in your JNI code? Shouldn't that be DisplayFileName instead?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top