Java JNI在应用程序中检测到错误:使用已删除的本地引用0x1

Java JNI在应用程序中检测到错误:使用已删除的本地引用0x1,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,我有一个Java函数,它的声明如下: public static void mathSendResults(final int kidId, final int points, final int correct, final int error, final float time, final String date, final long timestamp, final String description,

我有一个Java函数,它的声明如下:

public static void mathSendResults(final int kidId, final int points, final int correct, final int error, final float time,
                                       final String date, final long timestamp, final String description,
                                       final String settings, final int classNumber, final int level, final float percentage)
现在,我想通过JNI调用这个函数:

void NativeHelper::mathSendResults(int kidId, int points, int correct, int error, float time,
                            std::string date, long timestamp, std::string description,
                            std::string settings, int classNumber, int level, float percentage) {

    cocos2d::JniMethodInfo t;
    if (cocos2d::JniHelper::getStaticMethodInfo(t, AppActivityClassName, "mathSendResults",
                                                "(IIIIFLjava/lang/String;JLjava/lang/String;Ljava/lang/String;IIF)V")){

        jstring jdate = t.env->NewStringUTF(date.c_str());
        jstring jdescription = t.env->NewStringUTF(description.c_str());
        jstring jsettings = t.env->NewStringUTF(settings.c_str());

        t.env->CallStaticVoidMethod(t.classID, t.methodID, kidId, points, correct, error, time,
                                    jdate, timestamp, jdescription,
                                    jsettings, classNumber, level, percentage);

        t.env->DeleteLocalRef(t.classID);
        t.env->DeleteLocalRef(jdate);
        t.env->DeleteLocalRef(jdescription);
        t.env->DeleteLocalRef(jsettings);
    }
}
它应该可以工作,但应用程序崩溃并出现以下错误:

JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0x1

我觉得很奇怪。我已尝试删除
DeleteLocalRef
调用,但仍然崩溃。我已经使用了其他方法,但参数较少。我不确定这是否是原因。无论如何,我试着用int替换string(只是为了测试),这样参数的数量就不会改变了,而且效果很好。因此,这肯定是字符串对象的问题。我也尝试发送空字符串,但结果是一样的(所以它与字符串内容无关)。我还尝试将字符串数量减少到一个,但它仍然崩溃。

A
jmethodid
不是
jobject
,不需要(不能)删除。

经过大量尝试和错误,我终于修复了它

我不知道为什么,但是当jstring是第一个参数时,它就工作了。如果我在任何字符串应用程序崩溃之前放置一些东西(比如int)。以下代码是解决方案:

void NativeHelper::mathSendResults(int kidId, int points, int correct, int error, float time,
                            std::string date, long timestamp, std::string description,
                            std::string settings, int classNumber, int level, float percentage) {

//    final String date, final String description, final String settings,
//    final int kidId, final int points, final int correct, final int error, final int classNumber, final int level,
//    final float percentage, final float time,
//    final long timestamp

    cocos2d::JniMethodInfo t;
    if (cocos2d::JniHelper::getStaticMethodInfo(t, AppActivityClassName, "mathSendResults",
                                                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIIFFJ)V")){

        jstring jdate = t.env->NewStringUTF(date.c_str());
        jstring jdescription = t.env->NewStringUTF(description.c_str());
        jstring jsettings = t.env->NewStringUTF(settings.c_str());

        t.env->CallStaticVoidMethod(t.classID, t.methodID,
                                    jdate, jdescription, jsettings,
                                    kidId, points, correct, error, classNumber, level,
                                    percentage, time,
                                    timestamp);

        t.env->DeleteLocalRef(t.classID);
        t.env->DeleteLocalRef(jdate);
        t.env->DeleteLocalRef(jdescription);
        t.env->DeleteLocalRef(jsettings);
    }
}
爪哇:

为什么顺序很重要对我来说仍然是个谜


编辑:更新代码。实际上,第一个版本没有正常工作。一些int变量在Java代码中的值不正确(随机)。我必须通过类型对参数进行排序,然后它终于起作用了。

从哪里可以得到
t.classID
t.methodID
?这是一个标准的cocos2d-x JNI模板。
FindClass
返回的
jclass
是一个本地引用。方法/字段ID不是。即使我不删除内容,它仍然会崩溃。
public static void mathSendResults(final String date, final String description, final String settings,
                                   final int kidId, final int points, final int correct, final int error, final int classNumber, final int level,
                                   final float percentage, final float time,
                                   final long timestamp)