Мы наблюдаем java.lang.UnsatisfiedLinkError
на некоторых телефонах Android, которые используют наше приложение на рынке.
Описание проблемы:
static
{
System.loadLibrary("stlport_shared"); // C++ STL
System.loadLibrary("lib2");
System.loadLibrary("lib3");
}
Сбой приложения в одной из System.loadLibrary()
строк с java.lang.UnsatisfiedLinkError
. java.lang.UnsatisfiedLinkError: Couldn't load stlport_shared from loader dalvik.system.PathClassLoader[dexPath=/data/app/app_id-2.apk,libraryPath=/data/app-lib/app_id-2]: findLibrary returned null
Подход к решению
Мы начали запускать специальную диагностику для всех наших установок, чтобы проверить, распакована ли каждая библиотека в папке /data/data/app_id/lib
.
PackageManager m = context.getPackageManager();
String s = context.getPackageName();
PackageInfo p;
p = m.getPackageInfo(s, 0);
s = p.applicationInfo.dataDir;
File appDir = new File(s);
long freeSpace = appDir.getFreeSpace();
File[] appDirList = appDir.listFiles();
int numberOfLibFiles = 0;
boolean subFilesLarger0 = true;
for (int i = 0; i < appDirList.length; i++) {
if(appDirList[i].getName().startsWith("lib")) {
File[] subFile = appDirList[i].listFiles(FileFilters.FilterDirs);
numberOfLibFiles = subFile.length;
for (int j = 0; j < subFile.length; j++) {
if(subFile[j].length() <= 0) {
subFilesLarger0 = false;
break;
}
}
}
}
На каждом тестовом телефоне, который у нас есть numberOfLibFiles == 3
и subFilesLarger0 == true
. Мы хотели проверить, все ли библиотеки распакованы правильно и имеют размер больше 0 байт. Кроме того, мы смотрим на freeSpace
, чтобы узнать, сколько свободного места на диске. freeSpace
соответствует объему памяти, указанному в меню «Настройки» -> «Приложения» в нижней части экрана. Идея этого подхода заключалась в том, что, когда на диске недостаточно места, у установщика могут возникнуть проблемы с распаковкой APK.
Реальный сценарий
Судя по диагностике, на некоторых устройствах НЕ есть все 3 библиотеки в папке /data/data/app_id/lib
, но на них достаточно свободного места. Мне интересно, почему сообщение об ошибке ищет /data/app-lib/app_id-2
. Все наши телефоны хранят свои библиотеки в /data/data/app_id/lib
. Также System.loadLibrary()
должен использовать согласованный путь при установке и загрузке библиотек? Как я могу узнать, где ОС ищет библиотеки?
Вопрос
Кто-нибудь испытывает проблемы с установкой нативных библиотек? Какие обходные пути оказались успешными? Есть ли опыт простой загрузки нативных библиотек через Интернет, когда они не существуют, и сохранения их вручную? Что могло вызвать проблему в первую очередь?
ИЗМЕНИТЬ
Теперь у меня также есть пользователь, который сталкивается с этой проблемой после обновления приложения. Предыдущая версия отлично работала на его телефоне, а после обновления родные библиотеки кажутся пропавшими без вести. Копирование библиотек вручную, похоже, также вызывает проблемы. Он на Android 4.x с нерутированным телефоном без пользовательского ПЗУ.
РЕДАКТИРОВАНИЕ 2 – Решение
После 2 лет траты времени на эту проблему. Мы нашли решение, которое хорошо работает для нас сейчас. У нас открытый исходный код: https://github.com/KeepSafe/ReLinker.