我读了许多线程如何将* .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文件重建。
答案 0 :(得分:201)
在Android Studio 1.0.2中添加.so库
答案 1 :(得分:79)
当前解决方案
创建文件夹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)
}
相同的答案也可以在相关问题中找到:Include .so library in apk in android studio
答案 2 :(得分:25)
*。在Android Studio中设置库
你必须在android Studio项目中的main中生成jniLibs文件夹,并将所有.so文件放入其中。您还可以在build.gradle
中集成此行编译fileTree(dir:'libs',包括:[' .jar',' .so'])
完美的工作
| --app:
| - | --src:
| - | - | - 主
| - | - | - | --jniLibs
| - | - | - | - | --armeabi
| - | - | - | - | - | - 。so Files
这是项目结构。
答案 3 :(得分:20)
解决方案1:创建JniLibs文件夹
在您的应用中创建一个名为“jniLibs”的文件夹以及包含* .so的文件夹。 需要在与“Java”或“Assets”文件夹相同的文件夹中创建“jniLibs”文件夹。
解决方案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/
编辑它必须是jniLibs.srcDirs,而不是jni.srcDirs - 编辑代码。该目录可以是指向项目目录之外的[相对]路径。
答案 4 :(得分:12)
这是我的build.gradle文件,请注意
行jniLibs.srcDirs = ['libs']
这将包含libs&#39; s * .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')
}
答案 5 :(得分:3)
Android NDK官方hello-libs
CMake示例
刚刚在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)
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
如果您只支持某些体系结构,请参阅:Gradle Build NDK target only ARM
示例git跟踪预构建的共享库,但它也包含实际构建它们的构建系统:https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs
答案 6 :(得分:2)
使用本机库(所以文件) 您需要在“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'
答案 7 :(得分:0)
我使用打包在jar文件中的外部本机lib依赖项解决了类似的问题。有时这些体系结构依赖库一起打包在一个jar中,有时它们被分成几个jar文件。所以我写了一些buildscript来扫描本机库的jar依赖项,并将它们排序到正确的android lib文件夹中。此外,这还提供了一种下载maven repos中没有的依赖关系的方法,这种方法目前可用于让JNA在android上运行,因为并非所有本机jar都在public maven repos中发布。
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 :(得分:0)
我尝试了以上答案中的解决方案,但没有一个对我有用。 我有一个包含.so,.dll和.jar文件的库。 最后,我可以在这里看到详细信息: https://stackoverflow.com/a/54976458/7392868
我将.so文件复制粘贴到名为jniLibs的文件夹中,并将其粘贴到app / src / main /文件夹中。 对于其他依赖性,我使用了等级依赖性。
答案 9 :(得分:0)
我有 android studio 4.1.2,当我尝试在 File -> Project Structure -> Sdk Location 中设置 ndk 路径时,它会要求我下载 ndk,即使它已经安装,我设置了 NDK_HOME、ANDROID_NDK_HOME和 PATH 环境变量,什么也没有。唯一对我有用的是在 local.properties 中手动设置 ndk 版本,使用 ABI 及其各自的 .so 文件创建一个 jniLibs(是的,使用这个确切名称)文件夹,并在构建中指定 abi 过滤器和 ndk 版本.gradle。希望这能让其他人免于头痛。
local.properties
ndk.dir=C\:\\Users\\<user>\\AppData\\Local\\Android\\Sdk\\ndk\\22.0.7026061
build.gradle
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 22
targetSdkVersion 30
versionCode 1
versionName "1.0"
ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
sourceSets {
main {
jniLibs.srcDir 'jniLibs'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
ndkVersion '22.0.7026061'
}
...\app\src\main\
在 jniLibs 文件夹内