Подтвердить что ты не робот

Android ICS: ошибка JNI пытается использовать устаревшую локальную ссылку 0x1

После обновления моего телефона до андроида 4.03 ics моя игра dosent open больше, он просто закрывается без ошибок messege на deviCe и с этим на eclipse

04-02 16:55:27.672: E/dalvikvm(26884): JNI ERROR (app bug): attempt to use stale local reference 0x1
04-02 16:55:27.672: E/dalvikvm(26884): VM aborting

Моя игра в основном написана в java, но некоторые части находятся в c, и я думаю, что проблема (не очень сложно разобраться с его высказыванием JNI ERROR:))

Конечно, я не знаю, где проблема, поэтому я не даю никакого кода

У меня не было этой проблемы на Android 2.3

Я не знаю, помогает ли это, но иногда я получаю эту ошибку

04-02 16:55:26.061: E/Adreno200-ES11(26884): <qglDrvAPI_glTexImage2D:1913>: GL_STACK_UNDERFLOW
4b9b3361

Ответ 1

В то время как Ernest answer технически корректен, устаревшая локальная ссылка на что-то вроде 0x1 должна подсказывать вам, что Java VM пытается использовать что-то, а не объект Java, как объект Java.

Например, допустим, что ваша функция JNI:

JNI_EXPORT jboolean foobar(JNIEnv *env, jobject self) {
  ...
  return JNI_TRUE;
}

но вы ошибочно объявляете Java-копию как public native Boolean foobar() вместо public native Boolean foobar().

Это легко сделать, поскольку единственной разницей между boolean и boolean является капитализация.

  • boolean, примитивный тип, представлен в JNI как boolean
  • java.lang.Boolean, известный также как boolean, является типом класса, который представлен в JNI как jobject

При возврате из foobar Java VM будет обрабатывать значение JNI_TRUE (0x1), как если бы оно ссылалось на объект java.lang.Boolean, что приведет к этой фатальной ошибке.

Ответ 2

Ошибка "устаревшая локальная ссылка" означает, что вы сохраняете локальную ссылку на какой-либо объект Java между вызовами JNI; вам нужно преобразовать эту ссылку в глобальную ссылку, используя метод NewGlobalRef, прежде чем делать что-либо, что приведет к тому, что ссылка останется за пределами области одного вызова JNI.

Хотя это всегда было необходимо - это в спецификации JNI - только с Ice Cream Sandwich, что на самом деле вызывает проблемы на платформе Android.

Ответ 3

@Ernest и @Ilya верны. Обратите внимание, что проблема проявляется и другими способами, а не только несоответствия подписи. Есть еще один очень специфический случай, с которым я столкнулся, что было объяснено здесь в блоге команды Android в разделе:

Ошибка: Ошибочно полагая, что FindClass() возвращает глобальные ссылки

FindClass() возвращает локальные ссылки. Многие думают иначе. В системе без разгрузки классов (например, Android) вы можете обрабатывать jfieldID и jmethodID, как если бы они были глобальными. (Theyre на самом деле не ссылается, но в системе с разгрузкой классов есть похожие проблемы времени жизни.) Но jclass является ссылкой, а FindClass() возвращает локальные ссылки. Общим шаблоном ошибок является "статический jclass". Если вы вручную не перевернете свои локальные ссылки в глобальные ссылки, ваш код будет нарушен.

В основном я кэшировал jclass, возвращаемый FindClass в глобальной переменной as is, но оказывается, что это значение (с Android 4?) теперь является localref. В результате мне пришлось преобразовать его в globalref следующим образом:

jclass jc = env->FindClass(callbacks.name);
// Since Android ICS, class references are not global so we need to peg a
// global reference to the jclass returned by FindClass(), otherwise we get
// following error in the log:
// "JNI ERROR (app bug): attempt to use stale local reference 0xHHHHHHHH".
callbacks._class = static_cast<jclass>(env->NewGlobalRef(jc));

После большого количества царапин на голове это устранило проблему для меня.

Ответ 4

Это вариант ответа Эрнеста, вместо того, чтобы передавать логическое или даже логическое значение в качестве аргумента методу вызова, я передал литерал true (да, я часто пинал себя, когда обнаружил это), который, конечно, имеет значение 0x1.

Ответ 5

Не оспаривая справедливость других ответов, я потерял часы, преследуя эти ошибки. В моем случае они были действительно загадочными, но я только виноват:

10-16 12: 24: 18.722: E/dalvikvm (1204): JNI ERROR (ошибка приложения): попытка использовать устаревшую глобальную ссылку 0x26
10-16 12: 24: 18.722: E/dalvikvm (1204): прерывание VM

Для меня это означало, что я не запрашивал правильное разрешение в манифесте.