Heribert Heribert - 1 month ago 18
Android Question

Duplicate files during packaging of APK or UnsatisfiedLinkError Android

I have a Android project which uses libraries with interdependencies:

Android Application depends on the following native libraries


  • module tess-two (containing tesseract and leptonica)

  • module opencv4android

  • module mylibrary



mylibrary also depends on tess-two and opencv4android

The following is the build.gradle file of my Android Application:

apply plugin: 'com.android.application'

dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
compile project(':libraries:opencv4android')
compile project(':libraries:tess-two')
compile project(':libraries:mylibrary')
}

android {
compileSdkVersion 19
buildToolsVersion "22.0.1"


defaultConfig {
minSdkVersion 14
targetSdkVersion 19
}

// packagingOptions {
// exclude 'lib/armeabi/liblept.so'
// exclude 'lib/armeabi/libtess.so'
// exclude 'lib/armeabi-v7a/liblept.so'
// exclude 'lib/armeabi-v7a/libtess.so'
// exclude 'lib/mips/liblept.so'
// exclude 'lib/mips/libtess.so'
// exclude 'lib/x86/liblept.so'
// exclude 'lib/x86/libtess.so'
// }

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}

instrumentTest.setRoot('tests')
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}


A gradle build on this configuration fails with
duplicate files during packaging of APK
error due to
liblept.so
and
libtess.so
being copied twice.

When I uncomment the packaging options I can build successfully, however, I get an
UnsatisfiedLinkError
at runtime since
liblept.so
and
libtess.so
are not contained in the apk at all.

How can I get
liblept.so
and
libtess.so
to be included in the apk exactly once?

Answer

I think I found the solution, however, I do not quite understand it.

The build.gradle files of both modules mylibrary and tess-two contained a definition for

android.sourceSets.main.jniLibs.srcDirs = ['libs']

Commenting this definition in tess-two resulted in libtess.soand liblept.so being copied to the apk only once.

If someone understands this solution please leave a comment or answer.

Edit:

In the meantime I found a better solution: I added the following code to my main applications gradle.build file:

packagingOptions { // otherwise libtess.so and liblept.so are copied to apk twice resulting in an error
    pickFirst('lib/*/liblept.so')
    pickFirst('lib/*/libtess.so')
}