android apk JNI报告无法找到方法

时间:2013-09-17 10:11:34

标签: android java-native-interface jnienv

好吧,我的app java代码如下:

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);

    }
}

我的JNI代码是:

/* 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

我不知道为什么它总是报告,尽管我尽我所能。有人能帮助我吗?

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)

2 个答案:

答案 0 :(得分:4)

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

返回Class类,如NoSuchMethodError (...) in class Ljava/lang/Class;

所示

这是因为您的本机方法是静态的,因此不会将jobject传递给本机方法,而是传递给jclass。你的签名应该是:

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

然后您可以直接使用cls。

但是,您应该注意到,在静态方法中,没有对象可以调用您可以通过这种方式找到的方法。 (DisplayMessage非静态)

答案 1 :(得分:0)

我不确定你要做什么,我没有看到NtvPerformADT的调用可能会产生错误,但它可能与名为{{的函数有关。你的JNI代码中有1}}?那不应该是Java_DisplayMessage吗?