4
votes

I am trying to include my .so library from another directory. Compiling my project works fine. But when I run it, it gives me

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.company.gimikapp-2/base.apk"],nativeLibraryDirectories=[/data/app/com.company.gimikapp-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "libtheprebuiltlib.so"

Common solutions I see in SO is this:

sourceSets {
    main {
        jniLibs.srcDirs = ['src/main/jniLibs']
    }
}

Tried both

jniLibs.srcDirs = ['C:\\svn\\sys_libs']

and

jniLibs.srcDirs = ['C:/svn/sys_libs']

How do you actually point it to another directory outside your Android project?

This is my CMakeList.txt:

cmake_minimum_required(VERSION 3.4.1)
add_library( native-lib
            SHARED
            src/main/cpp/source/native-lib.cpp )
add_library(theprebuiltlib SHARED IMPORTED)
set_target_properties(theprebuiltlib PROPERTIES IMPORTED_LOCATION
            C:/svn/sys_libs/libtheprebuiltlib.so)
target_include_directories(
            native-lib PRIVATE
            src/main/cpp/source/
            C:/svn/sys_includes/)
find_library( log-lib
            log)
target_link_libraries( native-lib
            theprebuiltlib
            ${log-lib})

And here is my gradle setup for my JNI:

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
            ndk {
                abiFilters 'armeabi'
            }
        }
        ...
    }
    ...
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['C:/svn/sys_libs']
        }
    }
}
2
the medium.com link discusses a solution when .so is inside the android project. mine is outside the project, specifically in C:/svn/sys_libs/user1506104
Let's try to remove the jniLibs setting from build.gradle, and check how the APK changes. BTW, maybe the part where you launch cmake is incorrect, please post it here, too.Alex Cohn
added. hopefully it helps you help me. :)user1506104

2 Answers

3
votes

Apparently, you have NDK r17 installed and Android plugin v.3.1.0 or higher (we don't see this in the published fragment of build.gradle).

But you set abiFilters to armeabi, which has been dropped. You should set it to armeabi-v7a, and make sure that libtheprebuiltlib.so is also built for this ABI, or you can download an older version of NDK and in build.gradle dependencies set

classpath 'com.android.tools.build:gradle:3.0.1'

You can force the latest plugin handle armeabi if you set it explicitly:

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi'
        }
    }
}

(in your script, it is under android.defaultConfig.externalNativeBuild.ndk, so has no effect).

One mistake in your build.gradle, it should read

android {
  sourceSets {
     main { 
       jniLibs.srcDir 'C:/svn/sys_libs' 
     }
   }
}

when you have the file C:\svn\sys_libs\armeabi\libtheprebuiltlib.so. But this does not explain why cmake does not work as expected.

1
votes

For NDK r16 and Gradle plugin v3.1.2, here is the step by step solution (thanks to @Alex Cohn).

  1. Set android.sourceSets.main.jniLibs.srcDir to point to the location of external .so

    android {
        sourceSets {
            main { 
                jniLibs.srcDir 'C:/svn/sys_libs' 
            }
       }
    }
    
  2. Make sure that your external .so is located in the above path (step1), appended by correct architecture. In my case, it is armeabi, thus my .so is in

    C:/svn/sys_libs/armeabi/libtheprebuiltlib.so
    
  3. Move ndk from android.defaultConfig.externalNativeBuild.ndk to android.defaultConfig.ndk like so

    android {
        defaultConfig {
            ndk {
                abiFilters 'armeabi'
            }
        }
    }
    
  4. Make sure that CMakeLists.txt points to the complete path with proper architecture.

    set_target_properties(theprebuiltlib PROPERTIES IMPORTED_LOCATION
            C:/svn/sys_libs/armeabi/libtheprebuiltlib.so)