Question

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)
Was it helpful?

Solution

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)

OTHER TIPS

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?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top