我希望包含一个在我的Android Studio NDK项目中预编译的静态库。我正在使用Android Studio 1.0.1,任何在SO上尝试此问题的解决方案似乎已过时(或涉及创建库项目并包含它)。
结构如下:
app
/--src
/--main
/--java
+--jni
+--jniLibs
/--armeabi
/--libpng.a
--armeabiv7
/--libpng.a
...(for each abi)
我正在尝试包含库libpng。我尝试创建jniLibs(根据ph0b(很棒的指南,顺便说一句)并将libpng.a添加到相应的ABI文件夹。这仍然给我错误 - 找不到-llibpng 当我尝试使用以下代码进行编译:
ndk {
moduleName "game"
cFlags "-std=c++11 -fexceptions -DANDROID -I${project.buildDir}/../src/main/jni/include \
-I${project.buildDir}/../src/main/jni/include/png"
ldLibs "EGL", "GLESv3", "dl", "log", "android", "libpng"
stl "gnustl_static"
}
答案 0 :(得分:3)
现在可以通过实验性插件正常工作。
有关完整说明,请参阅this whole excellent article,这是我从中获取此信息的地方,但我也是自己使用它并且有效。
这是我的build.gradle
- 请注意,就我而言,它适用于图书馆项目,而且我使用静态链接而不是共享。
buildscript {
dependencies
{
classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha3"
}
}
apply plugin: 'com.android.model.library'
model {
repositories {
libs(PrebuiltLibraries) {
v8_base {
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_base.a")
}
}
v8_libbase {
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libbase.a")
}
}
v8_libplatform {
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libplatform.a")
}
}
v8_nosnapshot {
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_nosnapshot.a")
}
}
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
sources {
main {
jni {
source {
srcDir "src/main/jni"
}
dependencies {
library "v8_base" linkage "static"
library "v8_libbase" linkage "static"
library "v8_libplatform" linkage "static"
library "v8_nosnapshot" linkage "static"
}
}
}
}
ndk {
moduleName "v8example"
cppFlags.add("-std=c++11")
cppFlags.add("-I${file("src/main/jni/include")}".toString())
cppFlags.add("-fexceptions")
ldLibs.add("log")
stl "stlport_static"
abiFilters.add("armeabi armeabi-v7a x86")
}
}
}
另一种方法是使用旧的Gradle方法自行调用ndkBuild,从而使用.mk
文件。这也很好,但你失去了与Android Studio的良好集成,例如您的jni
文件正确显示。
答案 1 :(得分:1)
在Android Studio 1.0.2中添加.so库
答案 2 :(得分:1)
由于ndk支持现在限制在gradle中,你可以尝试使用不同abi的静态库。
ndk {
moduleName "game"
....
ldLibs ..., file(projectDir).absolutePath+"/src/main/jniLibs/\$(TARGET_ARCH_ABI)/libpng.a"
....
}
答案 3 :(得分:1)
你不能只包含.so文件,你还需要有src文件夹,它们实际上提供了访问那些.so文件中的方法的接口。我建议不要将你的项目与图书馆联系起来。
最好的方法是将它作为android studio中的库模块包含在内,并丢弃jni文件夹以禁用ndkbuild,并通过在build.gradle文件中添加以下内容将jnilib指向/ libs文件夹
jni.srcDirs = [] //disable automatic ndk-build call
jniLibs.srcDirs = [ 'libs' ] //no need to copy the .so files from /libs to /jniLibs folder
(检查libs目录是否已由android studio与.so文件正确导入)
将库导入为模块会自动执行以下操作
a)项目文件夹中的 yourlibrary 库文件夹,并根据gradle约定重新构建 b)导入项目(在settings.gradle中包含': yourlibrary ')和
c)创建依赖项(“文件 - >项目结构 - >从左侧子窗口中选择主应用程序模块 - >依赖项(最后一个选项卡) - >按右侧的绿色”+“ - > yourlibrary 作为模块依赖 - > OK“)
答案 4 :(得分:0)
这真的很难看,但它确实有效!您可以欺骗Gradle,允许您将代码注入生成的Android.mk文件中:
ndk {
abiFilter "armeabi-v7a"
// We need to inject the static library into the
// NDK build, and Gradle doesn't offer a way to directly
// modify the Android.mk file... So we hack it!
//
// You can see the end result at:
// build/intermediates/ndk/debug/Android.mk
moduleName "This_is_a_terrible_Gradle_hack\n" +
"include \$(CLEAR_VARS)\n" +
"LOCAL_MODULE := mystaticlib_prebuilt\n" +
"LOCAL_EXPORT_C_INCLUDES := mystaticlib/include\n" +
"LOCAL_SRC_FILES := mystaticlib/libmystaticlib.a\n" +
"include \$(PREBUILT_STATIC_LIBRARY)\n" +
"include \$(CLEAR_VARS)\n" +
"LOCAL_MODULE := MyActualModule\n" +
"LOCAL_STATIC_LIBRARIES += mystaticlib_prebuilt"
cFlags "-std=c++11 -fexceptions -frtti -pthread"
stl "gnustl_shared"
ldLibs "log", "OpenSLES", "z"
}