Pertanyaan Bagaimana cara memasukkan pustaka * .so di Android Studio?


Saya membaca banyak utas cara menambahkan pustaka * .so ke Android Studio, tetapi tidak ada yang berfungsi, terutama ketika menyangkut titik teks: Ini tidak bekerja dengan xxx yang lebih baru (Android Studio, gradle, ...)

Bisakah kita membuat awal yang segar, silakan. Saya mendapatkan:

Android Studio 0.6.0

Dari Struktur Proyek Saya melihat:

Lokasi SDK:

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

Proyek:

Gradle version 1.10
Android Plugin Version 0.11.+

Modul / aplikasi: Properti:

Susun Versi SDK 19 Versi Bangun Perangkat 19.1.0

Dependensi:

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

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

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

Saya mendapat file * .so yang sudah dikompilasi sebelumnya dan di aplikasi demo mereka bekerja. Saya harus mengubah kode sumber aplikasi, jadi saya perlu membangun ulang dengan file * .so yang sama.


74
2018-06-23 02:27


asal


Jawaban:


Solusi Saat Ini

Buat folder project/app/src/main/jniLibs, lalu masukkan *.so file dalam folder abi mereka di lokasi itu. Misalnya.,

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

Solusi tidak berlaku lagi

Tambahkan kedua cuplikan kode dalam file gradle.build modul Anda sebagai dependensi:

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

Cara membuat guci kustom ini:

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)
}

Jawaban yang sama juga dapat ditemukan dalam pertanyaan terkait: Sertakan .so perpustakaan di apk di studio android


46
2018-06-23 07:15



Menambah Perpustakaan .so di Android Studio 1.0.2

  1. Buat Folder "jniLibs" di dalam "src / main /"
  2. Masukkan semua perpustakaan .so Anda di dalam folder "src / main / jniLibs"
  3. Struktur folder seperti,
    | --app:
    | - | --src:
    | - | - | --main
    | - | - | - | --jniLibs
    | - | - | - | - | --armeabi
    | - | - | - | - | - | -. jadi File
    | - | - | - | - | --x86
    | - | - | - | - | - | -. jadi File
  4. Tidak perlu kode tambahan hanya menyinkronkan proyek Anda dan menjalankan aplikasi Anda.

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

192
2018-02-10 11:18



* .so perpustakaan di Android Studio

Anda harus membuat folder jniLibs di dalam main di proyek-proyek Android Studio dan meletakkan semua file .so Anda di dalamnya. Anda juga dapat mengintegrasikan baris ini dalam build.gradle

compile fileTree (dir: 'libs', termasuk: ['.botol','.begitu'])

Ini bekerja dengan sempurna

| --app:

| - | --src:

| - | - | --main

| - | - | - | --jniLibs

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

| - | - | - | - | - | -. jadi File

Ini adalah struktur proyek.


21
2017-08-27 07:24



Solusi 1: Membuat folder JniLibs

Buat folder bernama "jniLibs" ke dalam aplikasi Anda dan folder yang berisi * .so Anda di dalam. Folder "jniLibs" perlu dibuat di folder yang sama dengan folder "Java" atau "Aset" Anda.

Solusi 2: Modifikasi file build.gradle

Jika Anda tidak ingin membuat folder baru dan menyimpan file * .so Anda ke dalam folder libs, itu mungkin!

Dalam hal ini, cukup tambahkan file * .so Anda ke dalam folder libs (harap hormati arsitektur yang sama dengan solusi 1: libs / armeabi / .so misalnya) dan ubah file build.gradle aplikasi Anda untuk menambahkan direktori sumber dari jniLibs.

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

Anda akan memiliki lebih banyak penjelasan, dengan tangkapan layar untuk membantu Anda di sini (Langkah 6):

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

EDIT Itu harus jniLibs.srcDirs, bukan jni.srcDirs - mengedit kode. Direktori dapat berupa jalur [relatif] yang mengarah ke luar dari direktori proyek.


17
2018-03-24 14:07



Ini adalah file build.gradle saya, Harap catat barisnya

jniLibs.srcDirs = ['libs']

Ini akan menyertakan file * .soso libs ke 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')
}

12
2017-12-10 04:03



Untuk menggunakan native-library (jadi file) Anda perlu menambahkan beberapa kode dalam file "build.gradle".

Kode ini untuk membersihkan direktori "armeabi" dan menyalin file 'jadi' menjadi "armeabi" sementara "proyek bersih".

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

Saya sudah dirujuk dari bawah. https://gist.github.com/pocmo/6461138


2
2018-03-04 07:57



Android NDK resmi hello-libs Contoh CMake

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

Hanya bekerja untuk saya di Ubuntu 17.10 host, Android Studio 3, Android SDK 26, jadi saya sangat menyarankan Anda mendasarkan proyek Anda di atasnya.

Pustaka bersama disebut libgperf, bagian kode kunci adalah:

  • 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']
    

    Kemudian, jika Anda melihat ke bawah /data/app di perangkat, libgperf.so akan ada di sana juga.

  • pada kode C ++, gunakan: #include <gperf.h>

  • lokasi tajuk: hello-libs/distribution/gperf/include/gperf.h

  • lokasi lib: distribution/gperf/lib/arm64-v8a/libgperf.so

  • Jika Anda hanya mendukung beberapa arsitektur, lihat: Gradle Build NDK target hanya ARM

Contoh git melacak pustaka bersama prebuilt, tetapi git juga berisi sistem build untuk benar-benar membangunnya juga: https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs


1
2017-11-30 10:56



Saya telah memecahkan masalah yang sama menggunakan dependensi eksternal native lib yang dikemas dalam file jar. Terkadang perpustakaan dependend arsitektur ini dikemas semuanya di dalam satu toples, kadang-kadang mereka dipisah menjadi beberapa file jar. jadi saya menulis beberapa buildscript untuk memindai dependensi jar untuk libs asli dan menyortirnya ke folder lib android yang benar. Selain itu, ini juga menyediakan cara untuk mengunduh dependensi yang tidak ditemukan di repo maven yang saat ini berguna untuk membuat JNA bekerja di android karena tidak semua toples asli dipublikasikan di repo pakar publik.

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'])

0
2017-07-04 08:59