在jni GetStringUTFChars崩溃

时间:2019-03-18 10:41:16

标签: android c++ java-native-interface

Android应用程序很少崩溃,addr2line指向_JNIEnv::GetStringUTFChars(_jstring*, unsigned char*)

使用键调用该代码函数,将其传递给返回字符串的java函数,然后将其返回给初始调用者,该代码在应用程序的生存期内得到执行。

从Java端返回的值可以是empty stringnon empty string,而不能是null

可能是什么问题?可以不是该字符串中的非utf char吗?如果可以的话,我该如何处理?

std::string JNIcalls::Get(std::string key)
{
    std::string value = "";

#ifdef __ANDROID__
    // retrieve the JNI environment.
    JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();

    // retrieve the Java instance of the SDLActivity
    jobject activity = (jobject)SDL_AndroidGetActivity();
    if (activity == NULL) {
        return value;
    }

    // find the Java class of the activity. It should be SDLActivity or a subclass of it.
    jclass clazz(env->GetObjectClass(activity));
    if (clazz == NULL) {
        env->DeleteLocalRef(activity);
        return value;
    }

    // find the identifier of the method to call
    jmethodID method_id = env->GetStaticMethodID(clazz, "ImpJNIcallsGet", "(Ljava/lang/String;)Ljava/lang/String;");
    if (method_id == NULL) {
        env->DeleteLocalRef(activity);
        env->DeleteLocalRef(clazz);
        return value;
    }

    jstring jkey = env->NewStringUTF(key.c_str());
    if (jkey == NULL) {
        env->DeleteLocalRef(activity);
        env->DeleteLocalRef(clazz);
        return value;
    }

    // effectively call the Java method
    jstring rv = (jstring)env->CallStaticObjectMethod(clazz, method_id, jkey);
    if (rv != NULL) {
        const char *strReturn = env->GetStringUTFChars(rv, 0);

        int strlen_size = strlen(strReturn);
        for (int i = 0; i < strlen_size; i++)
        {
            value.append(1, strReturn[i]);
        }

        env->ReleaseStringUTFChars(rv, strReturn);
        env->DeleteLocalRef(rv);
    }
    // clean up the local references.
    env->DeleteLocalRef(activity);
    env->DeleteLocalRef(clazz);
    env->DeleteLocalRef(jkey);

#endif
    return value;
}

这是java返回代码:

    String returnValue = null;
    try {
        returnValue = futureResult.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

    if(returnValue == null) returnValue = "";
    return  returnValue;

0 个答案:

没有答案