简体   繁体   English

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

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

I have a .jar dependency which comes with .so library inside it. 我有一个.jar依赖项,里面有.so库。

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

The jar makes use of this .so library internally, and I'm building an Android app that makes use of the jar. jar在内部使用这个.so库,我正在构建一个使用jar的Android应用程序。

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. 一切都很好,直到我构建apk:通过使用7zip探索它,我发现.so文件已经消失,导致使用应用程序时的各种错误。

So is there any way to tell Gradle not to exclude the .so files when building? 那么有什么方法可以告诉Gradle在构建时不要排除.so文件? 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. 我不想将它们手动复制到我的Android项目中的文件夹中,因为我没有直接使用它们,但.jar库是加载它们的库。

Edit 1 : Adding build.gradle 编辑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')
}

Edit 2 : Here is the solution following the previous suggestions of @shizhen 编辑2:以下是@shizhen先前建议的解决方案

1- My .jar included the .so files in libs directory. 1-我的.jar包含libs目录中的.so文件。 I had to rename that to lib . 我不得不重命名为lib

2- I unpacked the .jar to gather the .so files. 2-我解压缩.jar以收集.so文件。

3- I created src/jniLibs folder and put the .so files, each in its respective <ANDROID_ABI> folder. 3-我创建了src/jniLibs文件夹并将.so文件放在各自的<ANDROID_ABI>文件夹中。

4- I modified the build.gradle file to include : 4-我修改了build.gradle文件以包含:

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

5 - Et voila! 5 - 瞧! The final .apk now includes the native libraries. 最终的.apk现在包括本机库。

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. 一切都很好,直到我构建apk:通过使用7zip探索它,我发现.so文件已经消失,导致使用应用程序时的各种错误。

I believe your jar dependency was not originally for android but generally for Java. 我相信你的jar依赖不是最初用于android而是通常用于Java。

Android app uses .dex format, so all your .jar dependencies will be repackaged into one or more dex files. Android应用程序使用.dex格式,因此所有.jar依赖项都将重新打包到一个或多个dex文件中。 You .so files won't be used as it is inside the jar. 您的.so文件将不会被使用,因为它在jar中。

So is there any way to tell Gradle not to exclude the .so files when building? 那么有什么方法可以告诉Gradle在构建时不要排除.so文件? 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. 我不想将它们手动复制到我的Android项目中的文件夹中,因为我没有直接使用它们,但.jar库是加载它们的库。

So, in order to adapt your jar to Android app, you HAVE TO unzip the jar taking out all the .so files and manually put them into src/jniLibs/<ANDROID_ABI>/ , eg 所以,为了你的罐子适应Android应用程序,你必须解压罐子取出所有的.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

Just a guess based on the Android docs on “Shrink your code and resources” : it seems that ProGuard is automatically used for release builds, in order to remove apparently unused code. 只是猜测基于Android文档“收缩你的代码和资源” :似乎ProGuard自动用于发布版本,以便删除明显未使用的代码。 You could try to disable that: 您可以尝试禁用它:

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

If that helps, then ProGuard would be your culprit. 如果这有帮助,那么ProGuard将是您的罪魁祸首。 Instead of leaving it disabled, you could then try to explicitly tell it to keep the files that must not be removed. 您可以尝试明确告诉它保留不得删除的文件 ,而不是将其禁用。

Simply set your sourceSets in build.gradle(Module: app) 只需在build.gradle中设置sourceSets(模块:app)

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

Use ndk if your project requried: 如果您的项目需要,请使用ndk:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM