Android NDK UnsatisfiedLinkError - удивительная причина
Обновление 8/7/2013:
Проблема решена сейчас, но причина ошибки была совершенно неожиданной, все обычные подозреваемые в таких ошибках были устранены с самого начала, и я узнал что-то новое. См. Мой ответ ниже.
Я довольно отчаянный здесь. У Android-приложения есть родная библиотека, откуда я вызываю метод. Никаких проблем во всех тестируемых системах, и программа не была в Google Play без каких-либо проблемных отчетов, используемых тысячами пользователей. Теперь, по-видимому, новый ROM - Android версии 4.2.2 - для телефона HTC One отсутствует. Пользователи утверждают, что это официальная сборка, обновленная форма официального канала. Когда они пытаются запустить мое приложение, он падает, а трассировка стека говорит:
java.lang.UnsatisfiedLinkError: собственный метод не найден...
и имя метода, о котором я знаю, существует и отлично работает некоторое время назад на том же устройстве, когда у них установлен Android 4.1. Я тестирую его под Android 4.2.2 в эмуляторах (не имею этого конкретного устройства), и проблем нет. Кроме того, пользователи попытались удалить и переустановить приложение с тем же результатом. Даже отправка им частной сборки без защиты ProGuard/Dexguard не помогает.
Что еще может вызвать java.lang.UnsatisfiedLinkError на Android? Или я должен предположить, что это HTC ROM просто глючит??? У кого-нибудь еще были подобные проблемы на HTC One с Android 4.2.2?
Редактировать 7/24/2013
В комментариях ниже другой разработчик предполагает, что система может иметь проблемы с поиском моей родной библиотеки. Я экспериментировал с эмулятором Genimotion 4.2.2, полностью удалив из него собственный файл библиотеки. Сообщение об ошибке отличается в этой ситуации, получено:
W/System.err: вызвано: java.lang.UnsatisfiedLinkError: не удалось загрузить cld из загрузчика dalvik.system.PathClassLoader [dexPath =/data/app/com.hyperionics.avar-2.apk, libra ryPath =/data/app-lib/com.hyperionics.avar-2]: findLibrary возвращается null
Пока в сообщениях трассировки стека я получил от пользователей HTC One с Android 4.2.2, я вижу это сообщение об ошибке:
Вызвано: java.lang.UnsatisfiedLinkError: собственный метод не найден: com.hyperionics.avar.CldWrapper.detectLangNative: (Ljava/lang/String;) [Ljava/lang/String;
Мне кажется, что система находит файл libcld.so по мере необходимости, но не находит способ, который ему там нужен. Зачем??? Я знаю, что метод существует, экспортируется по мере необходимости, и все остальные устройства и системы, также находящиеся под управлением Android 4.2.2, находят это. Только HTC One с 4.2.2 не работает...
Обновление 7/25/2013
Начну щедрость за 50 реп. очков, поскольку у меня нет HTC One и я застрял. Примите ответ, который указывает на способ решения проблемы - и отвечающий будет проверять мой код. чтобы показать, что это работает - или доказывает, что это действительно ошибка в недавнем ПЗУ Android 4.2.2 для HTC One. Это приложение https://play.google.com/store/apps/details?id=com.hyperionics.avar
Обновление 7/31/2013
В последний день щедрости и до сих пор нет ответов, нет предложений... До сих пор все такие сообщения об ошибках, которые я получаю из Европы, сообщили, что бренд "htc_europe" или "vodafone_fr". Возможно, ошибка локализована только в Европе (Франция + Германия)... Если есть кто-то там, где HTC One и Android обновлены до 4.2.2, мне будет интересно, если ошибка произойдёт в других странах или с другими провайдерами.
Грег
Ответы
Ответ 1
В течение щедрого периода не было удовлетворительного ответа. Я заказал устройство и вам придется отлаживать то, что, скорее всего, является системной ошибкой в устройстве ROM для обновления Android 4.2.2...
Обновление 6/20/2014 Еще одна причина случайного UnsatisfiedLinkError
Оказалось, что иногда при обновлении приложения из Google Play собственные библиотеки установлены неправильно. Может быть, у установщика заканчивается место или какая-то другая странная ошибка в системе. См. Также этот вопрос SO и ответы.
Обновление 8/6/2013 - тайна решена!
Мой HTC One, заказанный в Google Play, прибыл, и... тайна решена! Такая же авария произошла и на оригинальном Android 4.2.2 из Google Play. Проблема была в имени моей библиотеки: cld, которая создает общую библиотеку с именем libcld.so. По-видимому, у системы есть другая общая библиотека с тем же именем, где, конечно, нет методов, которых я ожидаю... Вероятно, какой-то "плагин" загрузил этот другой libcld.so в память процесса, а моя собственная библиотека была пропущена. Я переименовал родную библиотеку, и программа сразу же начала работать.
Я не знал о возможности такого столкновения имен на разных сборках Android... Кто-нибудь читал это, где-то в документах NDK было предупреждение? Наверное, теперь я буду приписывать все собственные библиотеки, которые я создаю, с именем моей компании или чем-то.
Ответ 2
Вы можете попробовать взять определение метода из своей библиотеки и переписать его в один из ваших классов, указав метод на другое имя. Это может быть очень утомительно, но по крайней мере вы можете быть уверены, что ваша программа сможет найти метод...
Ответ 3
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
}
}