如何告诉 Gradle 不要在我的 .jar 依赖项中排除 .so 文件?

How to tell Gradle not to exclude .so files in my .jar dependency?

我有一个 .jar 依赖项,其中包含 .so 库。

library.jar
       |
       -----com/company
              |
              -----.class files
       -----libs
              |
              -----libX.so

jar 在内部使用这个 .so 库,我正在构建一个使用 jar 的 Android 应用程序。

在我构建 apk 之前一切都很好:通过使用 7zip 探索它,我发现 .so 文件已经消失,导致使用应用程序时出现各种错误。

那么有什么办法告诉Gradle在构建时不要排除.so文件吗?我不想将它们手动复制到我的 Android 项目中的文件夹中,因为我没有直接使用它们,但是 .jar 库是加载它们的库。

编辑 1:添加 build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.company.myapp"
        minSdkVersion 24
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/lib1.jar')
    implementation files('libs/lib2.jar')
}

编辑2:这是按照@shizhen

先前建议的解决方案

1- 我的 .jar.so 文件包含在 libs 目录中。我不得不将其重命名为 lib.

2- 我解压缩了 .jar 以收集 .so 文件。

3- 我创建了 src/jniLibs 文件夹并将 .so 个文件放入各自的 <ANDROID_ABI> 文件夹中。

4- 我修改了 build.gradle 文件以包含:

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

5 - 瞧!最终 .apk 现在包括本机库。

只是基于 “Shrink your code and resources” 上的 Android 文档的猜测:ProGuard 似乎自动用于发布版本,以删除明显未使用的代码。您可以尝试禁用它:

// …
    buildTypes {
        release {
            minifyEnabled false
            useProguard false
        }
    }
// …

如果这有帮助,那么 ProGuard 就是您的罪魁祸首。您可以尝试显式 tell it to keep the files 来禁用它,而不是将其禁用。

Everything is good until after I build the apk : by exploring it using 7zip, I discover that the .so files have disappeared, leading to all sorts of errors when using the app.

我相信您的 jar 依赖项是 最初不是 android 但通常是 Java。

Android应用使用.dex格式,所以你所有的.jar依赖都会被重新打包成一个或多个dex文件。您 .so 文件将不会被使用,因为它在 jar 中。

So is there any way to tell Gradle not to exclude the .so files when building? I don't want to copy them manually into a folder in my Android Project, since I'm not using them directly, but the .jar library is the one loading them.

因此,为了使您的 jar 适应 Android 应用程序,您 必须 解压缩 jar 并取出所有 .so 个文件并 手动 将它们放入 src/jniLibs/<ANDROID_ABI>/,例如

jniLibs
    ├── arm64-v8a
    │   ├── libxxx.so
    │   └── libyyy.so
    ├── armeabi-v7a
    │   ├── libxxx.so
    │   └── libyyy.so
    ├── x86
    │   ├── libxxx.so
    │   └── libyyy.so
    └── x86_64
        ├── libxxx.so
        └── libyyy.so

只需在 build.gradle(Module: app)

中设置您的 sourceSets
android {
   ...
   ...
sourceSets {
    main {
        jniLibs.srcDirs = [
                './src/main/jniLibs'
        ]
    }
 }
}

如果您的项目需要,请使用 ndk:

defaultConfig {
    ...
    ndk {
        abiFilters "armeabi-v7a", "x86"
    }
}