Собственная библиотека Android (.so) - ошибка неудовлетворительной ссылки - PullRequest
1 голос
/ 13 марта 2019

Я недавно создал и опубликовал комплект приложений Android с скомпилированными нативными библиотеками для всех архитектур процессоров.На большинстве устройств все работает нормально.Но на некоторых устройствах я вижу эту ошибку в консоли Crashlytics Неустранимое исключение: java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader [DexPathList [[zip file "/system/framework/org.apache.http.legacy.boot.jar ", zip-файл" /data/app/com.someapp-wAu5DoLmLvM_RVnbU1qsCg==/base.apk"],nativeLibraryDirectories=[/data/app/com.someapp-wAu5DoLmLvM_RVnbU1/lib/ = libm64646464646464]]] не удалось найти "somemylib.so"

Мне интересно - почему это может произойти.У меня есть библиотеки для процессоров x64.Это происходит только на некоторых устройствах - но этот сбой является наиболее частым в Crashlytics.Все мои библиотеки хранятся в каталоге jniLibs. Это несколько фрагментов из моего build.gradle

bundle {
    density {
        // Different APKs are generated for devices with different screen densities; true by default.
        enableSplit false
    }
    abi {
        // Different APKs are generated for devices with different CPU architectures; true by default.
        enableSplit true
    }
    language {
        // This is disabled so that the App Bundle does NOT split the APK for each language.
        // We're gonna use the same APK for all languages.
        enableSplit false
    }
}
splits {
    abi {
        enable true
        reset()
        include 'armeabi', 'mips', 'x86', 'armeabi-v7a', 'arm64-v8a', 
 'mips64', 'x86_64'
    }
}
sourceSets {

    main {
        jniLibs.srcDirs = ['jniLibs']
    }
}

В моем приложении есть класс обслуживания, который пытается загрузить нативную библиотеку, когда кто-то ее запускает.Может быть, иногда этот «стартовый» вызов службы выполняется до того, как ОС сможет обнаружить собственные библиотеки в моем приложении?Но я не думаю, что это так.Можете ли вы помочь мне, пожалуйста

1 Ответ

2 голосов
/ 13 марта 2019

Ваша проблема не с кодом библиотеки, а с самими файлами .so. Устройства Android имеют основной ABI, набор инструкций, поддерживаемый процессором. Например, некоторые устройства с 64-разрядными процессорами используют ABI arm64-v8a.

Однако многие библиотеки и приложения еще не поддерживают 64-битные процессоры. Поэтому обычно новые процессоры также поддерживают вторичный ABI, который является более распространенным. Например, arm64-v8a процессоры обычно также поддерживают armeabi-v7a.

Когда приложение запускается, оно начинает искать собственные библиотеки в каталогах. Сначала он проверяет основной каталог ABI, arm64-v8a в этом примере. Если .so-файлов нет, он проверяет вторичный каталог ABI (armeabi-v7a). Если все еще не найден, вы получите ошибку, которую вы описали.

В вашем случае, как вы сказали, у вас есть файлы, так что это не проблема.

Одна большая проблема с этим выбором состоит в том, что он всегда придерживается основного ABI, если каталог существует. Это может привести к сбоям, если не все библиотеки предоставляют все файлы .so для всех ABI. Это описано здесь .

Вот пример: вы включаете в свое приложение 2 библиотеки: 1. VideoPlayerLibrary, которая имеет .so файлы для всех ABI 2. GifLibrary, которая имеет файлы .so только для armeabi и armeabi-v7a.

Теперь, если вы запустите приложение на устройстве arm64-v8a, оно будет придерживаться своего основного ABI, потому что оно нашло там файлы (.so файлы VideoPlayerLibrary). Но в тот момент, когда вы захотите воспроизвести GIF-файл, он попытается загрузить файлы .so из каталога arm64-v8a, но не найдет их там и вылетит, как в вашем сообщении с ошибкой ссылки.

Так что вы можете сделать?

У вас есть 2 варианта:

  1. Если ваша собственная библиотека содержит недостающие файлы .so, скомпилируйте ее для всех ABI. Если это не ваша собственная, проверьте, есть ли более новая версия, которая исправила эту проблему.
  2. Исключить неполные ABI из приложения. Таким образом, новые процессоры будут использовать вторичный ABI для запуска приложения. Это, конечно, приведет к ухудшению производительности, но не приведет к сбою. По моему опыту, наиболее важным ABI является armeabi-v7a, это должно поддерживаться, вероятно, всеми устройствами Android.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...