0. Проблема
Я создал библиотеку Android (aar), которая содержит некоторые файлы.
После успешной загрузки файла aar в мой проект приложения Android я пытаюсь загрузить файлы so (из классов aar), но не удается выполнить java.lang.UnsatisfiedLinkError
.
. Я думаю, что Приложение Android не ищет внутри aar для загрузки файлов so, но смотрит на папку lib, которая находится внутри приложения Android.
(я знаю, что могу скопировать эти разделяемые библиотеки напрямую в приложении android, но я не хочу этого делать)
1. Создайте библиотеку Android (aar)
build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
packagingOptions {
pickFirst 'lib/x86_64/libnanolcms.so'
pickFirst 'lib/x86/libnanolcms.so'
pickFirst 'lib/armeabi-v7a/libnanolcms.so'
pickFirst 'lib/arm64-v8a/libnanolcms.so'
pickFirst 'lib/x86_64/liblcms2.so'
pickFirst 'lib/x86/liblcms2.so'
pickFirst 'lib/armeabi-v7a/liblcms2.so'
pickFirst 'lib/arm64-v8a/liblcms2.so'
}
}
buildTypes {
release {
minifyEnabled false
debuggable false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
jniDebuggable = true
}
debug {
minifyEnabled false
debuggable false
jniDebuggable = true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
version '3.6.0'
path "src/main/jni/CMakeLists.txt"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jnilibs']
jni.srcDirs = [] //disable automatic ndk-build call
}
}
}
repositories {
flatDir {
dirs 'libs'
}
// to be able to compile opencv
maven { url "https://jitpack.io" }
}
dependencies {
implementation fileTree(include: ['*.jar','*.so'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation(name: 'openCV-3.3.1', ext: 'aar')
implementation "com.getkeepsafe.relinker:relinker:1.4.0"
}
из проекта библиотеки android
if (useReLinker) {
ReLinker.recursively().log(logcatLogger).loadLibrary(CXColorcatchManager.getInstance().getWeakContext().get(), libraryName, new ReLinker.LoadListener() {
@Override
public void success() {
CXLogger.verbose("Library " + libraryName + " successfully loaded");
libraryLoaderListener.onLibraryLoaded(true);
}
@Override
public void failure(Throwable t) {
CXLogger.verbose("Unable to load " + libraryName + " library \n");
libraryLoaderListener.onLibraryLoaded(false);
}
});
} else {
try {
System.loadLibrary(libraryName);
libraryLoaderListener.onLibraryLoaded(true);
} catch (Exception e) {
CXLogger.verbose("Unable to load " + libraryName + " library \n " + e);
libraryLoaderListener.onLibraryLoaded(false);
}
}
}
Как вы можете видеть на На следующем рисунке файл aar содержит файлы so. Они находятся в папке jni, которая является правильной папкой, следующей документации
my-library.aar
![enter image description here](https://i.stack.imgur.com/aX2Qk.png)
2. Android проект приложения
Я создал проект приложения Android, добавил файл aar в качестве зависимости (он работает нормально). Я вызываю класс Singleton, который я создал из файла aar, затем пытаюсь загрузить файл so из класса библиотеки, используя System.loadlibrary()
или Relinker .
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.colorix.spike.nano"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jnilibs']
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:runner:1.3.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha03'
// my library
implementation files('libs/my_library.aar')
implementation "com.getkeepsafe.relinker:relinker:1.4.0"
}
К сожалению, с System.loadlibrary()
он не находит библиотеку: java.lang.UnsatisfiedLinkError
Используя Relinker, я использую метод recursive () для проверки каждой папки:
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Loading the library normally failed: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk"],nativeLibraryDirectories=[/data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/lib/x86, /system/lib]]] couldn't find "libnanolcms.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1669)
at com.getkeepsafe.relinker.SystemLibraryLoader.loadLibrary(SystemLibraryLoader.java:24)
at com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:163)
at com.getkeepsafe.relinker.ReLinkerInstance.access$000(ReLinkerInstance.java:31)
at com.getkeepsafe.relinker.ReLinkerInstance$1.run(ReLinkerInstance.java:142)
at java.lang.Thread.run(Thread.java:764)
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: nanolcms (null) was not loaded normally, re-linking...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app /com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app /com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
[LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-YmXglPRjs_msSVzvsySnZA==/base.apk...
W/orix.spike.nan: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
W/orix.spike.nan: Accessing hidden method Landroid/view /ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
V/ReLinkerInstance: [LibraryLoadingTask.failure()-54]: Unable to load nanolcms library
Как видите, библиотека находится не в lib/<architecture/...
, а в aar, которая находится в папке jni.
Если я понимаю документацию android, папка lib является папкой android приложение, а не папка библиотеки android (aar).
Если кто-то знает, как загрузить файл so, находящийся внутри файла aar, пожалуйста, дайте мне знать. Если вам нужна дополнительная информация, дайте мне знать.
Решение (но я этого не хочу)
Я могу скопировать .so файлы в папку jniLibs приложения. Это будет работать правильно. Но это не то, что я хочу.