Как включить *.so библиотеку в Android Studio?

Я прочитал много потоков, как добавить библиотеку *.so в Android Studio, но никто из них не работает, особенно когда дело доходит до точки текста: это не работает с новым xxx (Android Studio, gradle,...)

Мы можем начать с нуля. Я получил:

Android Studio 0.6.0

Из структуры проекта я вижу:

Местоположение SDK:

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

Проект:

Gradle version 1.10
Android Plugin Version 0.11.+

Модули/приложение: Свойства:

Скомпилируйте Sdk Version 19 Build Tools Версия 19.1.0

Зависимости:

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

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

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

Я получил файлы *.so, предварительно скомпилированные, и в демонстрационном приложении они работают. Я должен изменить исходный код приложения, поэтому мне нужно перестроить с теми же файлами *.so.

Ответ 1

Создайте новую папку project/app/src/main/jniLibs, а затем поместите ваши файлы *.so со своими папками abi в это местоположение.

Устаревшее решение

Добавьте оба фрагмента кода в свой файл gradle.build в качестве зависимости:

compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.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)
}

Тот же ответ можно найти и в связанном с ним вопросе: Включить .so библиотеку в apk в андроид-студии

Ответ 2

Добавление .so Library в Android Studio 1.0.2

  • Создать папку "jniLibs" внутри "src/main/"
  • Поместите все ваши библиотеки .so внутри папки "src/main/jniLibs"
  • Структура папки выглядит,
    | --app:
    | - | --src:
    | - | - | --main
    | - | - | - | --jniLibs
    | - | - | - | - | --armeabi
    | - | - | - | - | - | - | -.
    | - | - | - | - | --x86
    | - | - | - | - | - | - | -.
  • Никакой дополнительный код не требует просто синхронизации вашего проекта и запуска вашего приложения.

    Ссылка
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main

Ответ 3

*. поэтому библиотека в Android Studio

Вам нужно создать папку jniLibs внутри main в проектах android Studio и поместить все ваши файлы .so внутри. Вы также можете интегрировать эту строку в build.gradle

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

Он отлично работает

| --app:

| - | --src:

| - | - | --main

| - | - | - | --jniLibs

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

| - | - | - | - | - | -. поэтому Файлы

Это структура проекта.

Ответ 4

Решение 1. Создание папки JniLibs

Создайте в своем приложении папку "jniLibs" и папки, содержащие ваш *.so внутри. Папка "jniLibs" должна быть создана в той же папке, что и папки "Java" или "Assets".

Решение 2. Модификация файла build.gradle

Если вы не хотите создавать новую папку и сохраняете свои файлы *.so в папке libs, это возможно!

В этом случае просто добавьте файлы *.so в папку libs (пожалуйста, соблюдайте ту же архитектуру, что и решение 1: libs/armeabi/.so) и измените файл build.gradle вашего приложения, чтобы добавить исходный каталог jniLibs.

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

У вас будет больше объяснений со скриншотами, которые помогут вам здесь (шаг 6):

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

Ответ 5

Это мой файл build.gradle, обратите внимание на строку

jniLibs.srcDirs = ['libs']

Это будет включать файл 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')
}

Ответ 6

Чтобы использовать собственную библиотеку (так что файлы) Вам нужно добавить некоторые коды в файл "build.gradle".

Этот код предназначен для очистки каталога "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'

Мне говорили о нижеследующем. https://gist.github.com/pocmo/6461138

Ответ 7

Я решил подобную проблему, используя внешние родственные зависимости lib, которые упакованы внутри файлов jar. Иногда эти библиотеки зависимостей архитектуры упаковываются все в одну банку, иногда они разбиваются на несколько файлов jar. поэтому я написал некоторый buildscript для сканирования зависимостей jar для родных libs и сортировки их в правильные папки Android для Android. Кроме того, это также обеспечивает способ загрузки зависимостей, которые не найдены в maven-репозиториях, которые в настоящее время полезны для работы JNA на андроиде, потому что не все родные банки публикуются в публичных репозиториях 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'])

Ответ 8

Официальный анонс Android NDK hello-libs Пример CMake

https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs

Просто работал у меня на хосте Ubuntu 17.10, Android Studio 3, Android SDK 26, поэтому я настоятельно рекомендую вам основывать свой проект на нем.

Общая библиотека называется libgperf, key code части:

  • hello-libs/app/src/main/cpp/CMakeLists.txt:

    // -L
    add_library(lib_gperf SHARED IMPORTED)
    set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION
              ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)
    
    // -I
    target_include_directories(hello-libs PRIVATE
                               ${distribution_DIR}/gperf/include)
    // -lgperf
    target_link_libraries(hello-libs
                          lib_gperf)
    
  • app/build.gradle:

    android {
        sourceSets {
            main {
                // let gradle pack the shared library into apk
                jniLibs.srcDirs = ['../distribution/gperf/lib']
    

    Затем, если вы посмотрите на /data/app на устройстве, там будет libgperf.so.

  • на С++-коде, используйте: #include <gperf.h>

  • расположение заголовка: hello-libs/distribution/gperf/include/gperf.h

  • Местоположение: distribution/gperf/lib/arm64-v8a/libgperf.so

  • Если вы поддерживаете только некоторые архитектуры, см. Gradle Создание только NDK-цели только ARM

Пример git отслеживает готовые совместно используемые библиотеки, но он также содержит систему сборки, чтобы фактически их создать: https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs