使用Android NDK获取ANDROID_ID时出现过期的本地引用错误

3

我正在开发一个应用程序,其中一个要求是通过 NDK 收集设备的 ANDROID_ID

在查看了无数的线程、答案和参考资料之后,我想出了一个初始实现方案,它调用了我用于执行 Java 和 Native 层之间所有交互的类上的静态方法。唯一的问题是,当检索 ANDROID_ID 时,它会抛出下面的错误,并在此后退出。

JNI ERROR (app bug): accessed stale local reference 0x5d6892a9 (index 9386 in a table of size 11)

我知道错误发生在最后一个函数调用(CallStaticObjectMethod)上,因为我已经尝试添加日志来跟踪它,并且它顺利执行了其他所有内容。下面是我当前使用的代码:

SampleActivity.java

class SampleActivity {

    // ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        NativeService.initialize(this);

        // ...
    }
}

NativeService.java

public class NativeService {

    // ...

    public native static boolean initialize(Context ctx);
}

Native.cpp

JNIEXPORT jboolean JNICALL Java_com_company_mobile_NativeService_initialize(JNIEnv * env, jobject obj,
    jobject ctx
) {
    jclass contextClass = env->GetObjectClass(ctx);
    if (contextClass == NULL) {
        return false;
    }

    jmethodID getContentResolverMID = env->GetMethodID(contextClass, "getContentResolver", "()Landroid/content/ContentResolver;");
    if (getContentResolverMID == NULL) {
        return false;
    }

    jobject contentResolverObj = env->CallObjectMethod(ctx, getContentResolverMID);
    if (contentResolverObj == NULL) {
        return false;
    }

    jclass settingsSecureClass = env->FindClass("android/provider/Settings$Secure");
    if (settingsSecureClass == NULL) {
        return false;
    }

    jmethodID getStringMID = env->GetStaticMethodID(settingsSecureClass, "getString", "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");
    if (getStringMID == NULL) {
        return false;
    }

    // Offending line
    jstring androidId = (jstring) env->CallStaticObjectMethod(settingsSecureClass, getStringMID, contentResolverObj, "android_id");
    if (androidId == NULL) {
        return false;
    }

    return (strcmp((char *)androidId, "0123456789ABCDEF") == 0);
}
1个回答

1
getString方法的第二个参数应该是java/lang/String的一个实例。字面量"android_id"char数组,它会衰减为(const)char*
要从const char*字符串构造一个java/lang/String实例,您应该使用JNI函数NewStringUTF
jstring idStr = (jstring) env->NewStringUTF("android_id");
// Do relevant error checking, and then:
jstring androidId = (jstring) env->CallStaticObjectMethod(settingsSecureClass, getStringMID, contentResolverObj, idStr);

没错,就是这个问题,非常感谢!我还忘记了对androidId使用GetStringUTFChars(),以便能够使用strcmp。保留此评论以防其他人遇到相同的问题。 - rmobis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接