【问题标题】:Get ANDROID_ID using Android NDK - stale local reference error使用 Android NDK 获取 ANDROID_ID - 过时的本地引用错误
【发布时间】:2015-09-01 17:43:35
【问题描述】:

我正在开发一个应用程序,其中一个要求是我通过 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);
}

【问题讨论】:

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


    【解决方案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);
    

    【讨论】:

    • 原来如此,非常感谢!虽然我也忘记了GetStringUTFChars() androidId 这样我就可以使用strcmp 了。保留此评论以防万一有人遇到同样的问题。
    猜你喜欢
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多