Android Studioに* .soライブラリを含める方法は?


123

* .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バージョン19ビルドツールバージョン19.1.0

依存関係:

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

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

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

* .soファイルを事前にコンパイルし、デモアプリで動作しています。アプリのソースコードを変更する必要があるため、同じ* .soファイルで再構築する必要があります。


Androidのプロジェクト以外のディレクトリからの.soファイルを追加します。stackoverflow.com/questions/50713933/...
user1506104

ここで答えを確認してください:stackoverflow.com/a/54977264/8034839
shizhen

回答:


108

現在のソリューション

フォルダを作成し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

非推奨のソリューション

両方のコードスニペットを依存関係としてモジュールgradle.buildファイルに追加します。

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

同じ答えが関連する質問にもあります:AndroidスタジオのAPKに.soライブラリを含めます


6
Compileタスクは廃止されました。使用するJavaCompile代わりに(関連の回答から)
セルギ

タスクはどこに置くべきですか?
masoud vali 2016

2
まずjniLibsフォルダーソリューションを試してください。このタスクはapp / library gradle.buildファイルに配置する必要があります。
nenick

GradleプラグインユーザーガイドjniLibsディレクトリパスのリファレンス-プロジェクトの構造
Eido95

ここにも(リスト異なるアーキテクチャのサブフォルダ)を参照してください。cumulations.com/blogs/9/...
NorbertM

222

Android Studio 1.0.2での.soライブラリの追加

  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

6
これはStudioの2015年6月16日ベータ版では機能しません
バグ修正プログラム

6
これは正解です。AndroidStudio 1.2.2で動作します。チェックおよび確認済み。
Akhil Jain

3
Android Studio 1.3.1での作業。
ハイメHablutzel 2015

3
私のために働いたthnx。android studio 2.1.2で:)
ShujatAli

3
Android Studio 3.2.1で動作します。まだどこにも文書化されていません!???
NorbertM 2018年

29

解決策1:JniLibsフォルダーの作成

アプリに「jniLibs」というフォルダーを作成し、*。soを含むフォルダーを作成します。「jniLibs」フォルダーは、「Java」または「Assets」フォルダーと同じフォルダーに作成する必要があります。

解決策2:build.gradleファイルの変更

新しいフォルダを作成せずに、*。soファイルをlibsフォルダに保存する場合は、可能です。

その場合は、*。soファイルをlibsフォルダーに追加し(ソリューション1と同じアーキテクチャを尊重してください:たとえばlibs / armeabi / .so)、アプリのbuild.gradleファイルを変更してソースディレクトリを追加します。 jniLibsの。

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

ここで役立つスクリーンショットを使用して、より多くの説明があります(ステップ6):

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

編集それはjni.srcDirsではなくjniLibs.srcDirsでなければなりませんでした-コードを編集しました。ディレクトリは、プロジェクトディレクトリの外部を指す[相対]パスにすることができます。


1
ソリューション2が機能しません。ビルドエラーが発生しました:「ソースセット 'main'でプロパティ 'jni'が見つかりませんでした。」
グレッグブラウン

その秘密は、「jniLibs」フォルダを「Java」または「Assets」フォルダと同じフォルダに作成する必要があることでした。ありがとう!
セラフィムの

方法1では正しくコンパイルでき、2つ目ではASに「cpp」フォルダーが作成され、C ++コンパイラーがないというエラーが表示されました
fillobotto

ソリューション2では、jni.srcDirsではなくjniLibs.srcDirsを使用して、ネイティブライブラリの場所を指定する必要がありました(パスは相対パスまたは絶対パスで、プロジェクトディレクトリの外部を指すこともできます)。
astraujums 2018年

ソリューション2の場合は、source Sets {コードをandroid {セクションの下に配置する必要があります
yennster

26

Android Studioの* .soライブラリ

Android Studioプロジェクトのmain内にjniLibsフォルダーを生成し、すべての.soファイルを中に置く必要があります。この行をbuild.gradleに統合することもできます

コンパイルfileTree(dir: 'libs'、include:['.jar '、 ' .so'])

それは完璧に機能します

| --app:

|-| --src:

|-|-| --main

|-|-|-| --jniLibs

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

|-|-|-|-|-|-。soファイル

これがプロジェクトの構造です。


4
コンパイルfileTree(dir: 'libs'、include:['. jar '、 ' 。so '])に.soを追加すると、私の問題が解決しました。thnx
BST Kaal

それでも以下の解決策の後である場合は、android ndk r10e
Vineet Setia

12

これは私のbuild.gradleファイルです、行に注意してください

jniLibs.srcDirs = ['libs']

これには、apkにlibsの* .soファイルが含まれます。

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

5

Android NDK公式hello-libsCMakeの例

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

Ubuntu 17.10ホスト、Android Studio 3、Android SDK 26で私のために働いただけなので、プロジェクトをベースにすることを強くお勧めします。

共有ライブラリはと呼ばれlibgperf、主要なコード部分は次のとおりです。

  • 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そこにもいるでしょう。

  • C ++コードでは、以下を使用します。 #include <gperf.h>

  • ヘッダーの場所: hello-libs/distribution/gperf/include/gperf.h

  • libの場所: distribution/gperf/lib/arm64-v8a/libgperf.so

  • 一部のアーキテクチャのみをサポートする場合は、ARMのみを対象とするGradleビルドNDKを参照してください。

サンプルのgitは事前にビルドされた共有ライブラリを追跡しますが、実際にそれらをビルドするためのビルドシステムも含まれています


2

ネイティブライブラリ(soファイル)を使用するには "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


2

jarファイル内にパッケージ化されている外部ネイティブlib依存関係を使用して、同様の問題を解決しました。これらのアーキテクチャに依存するライブラリは、1つのjar内にまとめてパッケージ化される場合もあれば、いくつかのjarファイルに分割される場合もあります。そのため、ネイティブlibのjar依存関係をスキャンし、それらを正しいandroid libフォルダーに並べ替えるためのビルドスクリプトをいくつか作成しました。さらに、これにより、Mavenリポジトリにない依存関係をダウンロードする方法も提供されます。これは、現在すべてのネイティブjarがパブリックMavenリポジトリで公開されているわけではないため、AndroidでJNAを動作させるのに現在便利です。

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

上記の回答で解決策を試しましたが、どれもうまくいきませんでした。.so、.dll、および.jarファイルを含むライブラリがありました。最後にこれを行いました、詳細はこちらで確認できます:https : //stackoverflow.com/a/54976458/7392868

jniLibsという名前のフォルダーに.soファイルをコピーして貼り付け、app / src / main /フォルダー内に貼り付けました。他の依存関係については、グレードの依存関係を使用しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.