如何在 Android Studio 中包含 *.so 库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24357687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:03:13  来源:igfitidea点击:

How to include *.so library in Android Studio?

androidandroid-studio

提问by Ronald Wiplinger

I read many threads how to add a *.so library to Android Studio, but none of them works, especially when it comes to the point of text: This does not work with the newer xxx (Android Studio, gradle, ...)

我阅读了许多线程如何将 *.so 库添加到 Android Studio,但它们都不起作用,尤其是在涉及文本时:这不适用于较新的 xxx(Android Studio、gradle,...)

Can we make a fresh start please. I got:

我们可以重新开始吗?我有:

Android Studio 0.6.0

安卓工作室 0.6.0

From Project Structure I see:

从项目结构我看到:

SDK Location:

SDK位置:

/usr/share/android-studio/data/sdk
/usr/lib/jvm/default-java

Project:

项目:

Gradle version 1.10
Android Plugin Version 0.11.+

Modules/app: Properties:

模块/应用程序: 属性:

Compile Sdk Version 19 Build Tools Version 19.1.0

编译 Sdk 版本 19 构建工具版本 19.1.0

Dependencies:

依赖项:

{dir=libs, include=[*.jar]} Compile

{dir=libs, include=[*.so]}  Provided

m com.android.support: appcompat -v7:19.+   Compile

I got the *.so files pre-compiled and at the demo app they are working. I have to change the source code of the app, so I need to rebuild with the same *.so files.

我得到了预编译的 *.so 文件,并且在他们正在运行的演示应用程序中。我必须更改应用程序的源代码,因此我需要使用相同的 *.so 文件进行重建。

采纳答案by nenick

Current Solution

当前解决方案

Create the folder project/app/src/main/jniLibs, and then put your *.sofiles within their abi folders in that location. E.g.,

创建文件夹project/app/src/main/jniLibs,然后将您的*.so文件放在该位置的 abi 文件夹中。例如,

project/
├──libs/
|  └── *.jar       <-- if your library has jar files, they go here
├──src/
   └── main/
       ├── AndroidManifest.xml
       ├── java/
       └── jniLibs/ 
           ├── arm64-v8a/                       <-- ARM 64bit
           │   └── yourlib.so
           ├── armeabi-v7a/                     <-- ARM 32bit
           │   └── yourlib.so
           └── x86/                             <-- Intel 32bit
               └── yourlib.so

Deprecated solution

已弃用的解决方案

Add both code snippets in your module gradle.build file as a dependency:

在你的模块 gradle.build 文件中添加两个代码片段作为依赖:

compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')

How to create this custom jar:

如何创建这个自定义 jar:

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}

Same answer can also be found in related question: Include .so library in apk in android studio

在相关问题中也可以找到相同的答案:Include .so library in apk in android studio

回答by Vasanth

Adding .so Library in Android Studio 1.0.2

在 Android Studio 1.0.2 中添加 .so 库

  1. Create Folder "jniLibs" inside "src/main/"
  2. Put all your .so libraries inside "src/main/jniLibs" folder
  3. Folder structure looks like,
    |--app:
    |--|--src:
    |--|--|--main
    |--|--|--|--jniLibs
    |--|--|--|--|--armeabi
    |--|--|--|--|--|--.so Files
    |--|--|--|--|--x86
    |--|--|--|--|--|--.so Files
  4. No extra code requires just sync your project and run your application.

    Reference
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main
  1. 在“src/main/”中创建文件夹“jniLibs”
  2. 将所有 .so 库放在“src/main/jniLibs”文件夹中
  3. 文件夹结构看起来像,
    |--app:
    |--|--src:
    |--|--|--main
    |--|--|--|--jniLibs
    |--|--|-- |--|--armeabi
    |--|--|--|--|--|--.so 文件
    |--|--|--|--|--x86
    |--|-- |--|--|--|--.so 文件
  4. 没有额外的代码只需要同步您的项目并运行您的应用程序。

    参考
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main

回答by GuillaumeAgis

Solution 1 : Creation of a JniLibs folder

解决方案 1:创建 JniLibs 文件夹

Create a folder called “jniLibs” into your app and the folders containing your *.so inside. The "jniLibs" folder needs to be created in the same folder as your "Java" or "Assets" folders.

在您的应用程序和包含您的 *.so 的文件夹中创建一个名为“jniLibs”的文件夹。“jniLibs”文件夹需要在与“Java”或“Assets”文件夹相同的文件夹中创建。

Solution 2 : Modification of the build.gradle file

方案二:修改build.gradle文件

If you don't want to create a new folder and keep your *.so files into the libs folder, it is possible !

如果您不想创建新文件夹并将 *.so 文件保存在 libs 文件夹中,则可以!

In that case, just add your *.so files into the libs folder (please respect the same architecture as the solution 1 : libs/armeabi/.so for instance) and modify the build.gradle file of your app to add the source directory of the jniLibs.

在这种情况下,只需将您的 *.so 文件添加到 libs 文件夹中(请尊重与解决方案 1 相同的架构:例如 libs/armeabi/.so)并修改您的应用程序的 build.gradle 文件以添加源目录jniLibs。

sourceSets {
    main {
        jniLibs.srcDirs = ["libs"]
    }
}

You will have more explanations, with screenshots to help you here ( Step 6 ):

你会有更多的解释,这里有截图来帮助你(步骤 6):

http://blog.guillaumeagis.eu/setup-andengine-with-android-studio/

http://blog.guillaumeagis.eu/setup-andengine-with-android-studio/

EDITIt had to be jniLibs.srcDirs, not jni.srcDirs - edited the code. The directory can be a [relative] path that points outside of the project directory.

编辑它必须是 jniLibs.srcDirs,而不是 jni.srcDirs - 编辑了代码。该目录可以是指向项目目录之外的 [相对] 路径。

回答by Ramkailash

*.so library in Android Studio

Android Studio 中的 *.so 库

You have to generate jniLibs folder inside main in android Studio projects and put your all .so files inside. You can also integrate this line in build.gradle

您必须在 android Studio 项目的 main 中生成 jniLibs 文件夹,并将所有 .so 文件放入其中。您还可以将此行集成到 build.gradle 中

compile fileTree(dir: 'libs', include: ['.jar','.so'])

编译文件树(目录:'libs',包括:['. jar','.so'])

It's work perfectly

它完美地工作

|--app:

|--应用程序:

|--|--src:

|--|--src:

|--|--|--main

|--|--|--main

|--|--|--|--jniLibs

|--|--|--|--jniLibs

|--|--|--|--|--armeabi

|--|--|--|--|--armeabi

|--|--|--|--|--|--.so Files

|--|--|--|--|--|--.so 文件

This is the project structure.

这是项目结构。

回答by NovemberEleven

This is my build.gradle file, Please note the line

这是我的 build.gradle 文件,请注意这一行

jniLibs.srcDirs = ['libs']

This will include libs's *.so file to apk.

这将包括 libs 的 *.so 文件到 apk。

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

    // Move the tests to tests/java, tests/res, etc...
    instrumentTest.setRoot('tests')

    // Move the build types to build-types/<type>
    // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
    // This moves them out of them default location under src/<type>/... which would
    // conflict with src/ being used by the main source set.
    // Adding new build types or product flavors should be accompanied
    // by a similar customization.
    debug.setRoot('build-types/debug')
    release.setRoot('build-types/release')
}

回答by pretty angela

To use native-library (so files) You need to add some codes in the "build.gradle" file.

要使用 native-library(so 文件),您需要在“build.gradle”文件中添加一些代码。

This code is for cleaing "armeabi" directory and copying 'so' files into "armeabi" while 'clean project'.

此代码用于清除“armeabi”目录并将“so”文件复制到“armeabi”中,同时“清理项目”。

task copyJniLibs(type: Copy) {
    from 'libs/armeabi'
    into 'src/main/jniLibs/armeabi'
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(copyJniLibs)
}
clean.dependsOn 'cleanCopyJniLibs'

I've been referred from the below. https://gist.github.com/pocmo/6461138

我是从下面提到的。 https://gist.github.com/pocmo/6461138

回答by Jan

I have solved a similar problem using external native lib dependencies that are packaged inside of jar files. Sometimes these architecture dependend libraries are packaged alltogether inside one jar, sometimes they are split up into several jar files. so i wrote some buildscript to scan the jar dependencies for native libs and sort them into the correct android lib folders. Additionally this also provides a way to download dependencies that not found in maven repos which is currently usefull to get JNA working on android because not all native jars are published in public maven repos.

我已经使用打包在 jar 文件中的外部本机 lib 依赖项解决了类似的问题。有时这些架构依赖库被打包在一个 jar 中,有时它们被分成几个 jar 文件。所以我写了一些构建脚本来扫描本地库的 jar 依赖项,并将它们分类到正确的 android lib 文件夹中。此外,这还提供了一种下载 maven 存储库中未找到的依赖项的方法,这对于让 JNA 在 android 上工作非常有用,因为并非所有本机 jar 都发布在公共 Maven 存储库中。

android {
    compileSdkVersion 23
    buildToolsVersion '24.0.0'

    lintOptions {
        abortOnError false
    }


    defaultConfig {
        applicationId "myappid"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ["src/main/jniLibs", "$buildDir/native-libs"]
        }
    }
}

def urlFile = { url, name ->
    File file = new File("$buildDir/download/${name}.jar")
    file.parentFile.mkdirs()
    if (!file.exists()) {
        new URL(url).withInputStream { downloadStream ->
            file.withOutputStream { fileOut ->
                fileOut << downloadStream
            }
        }
    }
    files(file.absolutePath)
}
dependencies {
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'net.java.dev.jna:jna:4.2.0'
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-arm.jar?raw=true', 'jna-android-arm')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-armv7.jar?raw=true', 'jna-android-armv7')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-aarch64.jar?raw=true', 'jna-android-aarch64')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86.jar?raw=true', 'jna-android-x86')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86-64.jar?raw=true', 'jna-android-x86_64')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips.jar?raw=true', 'jna-android-mips')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips64.jar?raw=true', 'jna-android-mips64')
}
def safeCopy = { src, dst ->
    File fdst = new File(dst)
    fdst.parentFile.mkdirs()
    fdst.bytes = new File(src).bytes

}

def archFromName = { name ->
    switch (name) {
        case ~/.*android-(x86-64|x86_64|amd64).*/:
            return "x86_64"
        case ~/.*android-(i386|i686|x86).*/:
            return "x86"
        case ~/.*android-(arm64|aarch64).*/:
            return "arm64-v8a"
        case ~/.*android-(armhf|armv7|arm-v7|armeabi-v7).*/:
            return "armeabi-v7a"
        case ~/.*android-(arm).*/:
            return "armeabi"
        case ~/.*android-(mips).*/:
            return "mips"
        case ~/.*android-(mips64).*/:
            return "mips64"
        default:
            return null
    }
}

task extractNatives << {
    project.configurations.compile.each { dep ->
        println "Scanning ${dep.name} for native libs"
        if (!dep.name.endsWith(".jar"))
            return
        zipTree(dep).visit { zDetail ->
            if (!zDetail.name.endsWith(".so"))
                return
            print "\tFound ${zDetail.name}"
            String arch = archFromName(zDetail.toString())
            if(arch != null){
                println " -> $arch"
                safeCopy(zDetail.file.absolutePath,
                        "$buildDir/native-libs/$arch/${zDetail.file.name}")
            } else {
                println " -> No valid arch"
            }
        }
    }
}

preBuild.dependsOn(['extractNatives'])

回答by Muhammad Ali

I tried the solutions in the above answers but none worked for me. I had a library with .so,.dll and .jar files. At the end I did this, you can see the details here: https://stackoverflow.com/a/54976458/7392868

我尝试了上述答案中的解决方案,但没有一个对我有用。我有一个包含 .so、.dll 和 .jar 文件的库。最后我这样做了,你可以在这里看到详细信息:https: //stackoverflow.com/a/54976458/7392868

I copy pasted the .so files in a folder named jniLibs and pasted it inside app/src/main/ folder. For other dependencies I used the grade dependencies.

我将 .so 文件复制粘贴到名为 jniLibs 的文件夹中,并将其粘贴到 app/src/main/ 文件夹中。对于其他依赖项,我使用了等级依赖项。