我有一个奇怪的问题。我有一个aar库,它包含并使用本机.so库。现在,我想编写另一个lib,它依赖于该库,并且还具有本机部分,具体取决于来自第一个lib的本机lib。依赖库使用第一个lib中的本机代码和java包装器。
我想知道,有没有办法,如何通过标准gradle依赖(使用第一个lib中复制的头文件)来做到这一点?或者我是否可以直接从源代码构建第二个库?
为什么我需要这个: 我们有一个具有基本功能的多平台lib,用于android as aar。这个lib可以在标准的android应用程序中使用,我们在多个项目中使用它,它没有其他本机代码。
但在一个应用程序中,我们想要编写多平台共享应用程序代码,具体取决于lib,我希望将这些库分开。
谢谢!
答案 0 :(得分:6)
Here是基于CharAdapter.adapt("xyz").forEach(System.out::print)
的基本可行示例,您可以对OpenCV
执行相同操作。
打包first lib
,jar
并导出*.so
(请参阅链接项目中的文件headers
如何将标题附加到aar)。
例如,您可以OpenCV4Android/opencv/build.gradle
建立first.aar
。
根据需要在其他项目中添加first lib
。
first.aar
将本机库链接到本机构建系统中的allprojects {
repositories {
jcenter()
flatDir {
dirs '/path/to/aar'
}
}
}
// in your app's build.gradle
dependencies {
// ...
compile 'com.example:example-with-header@aar'
// ...
}
。
如果您使用first.aar
,它应该如下所示
CMake
答案 1 :(得分:1)
正如你提到的Gradle,我假设你正在使用 最新的Android Studio。我使用1.2.2并且发现它很容易 从浮动的许多教程中构建简单的NDK项目 周围,但令人沮丧的难以建立一个NDK项目 任何复杂性。我会总结一下我的发现,但我非常高兴 建议阅读 this blog 和this StackOverflow。
我的项目与您的项目类似,但并不完全相同。我的诀窍 正在弄清楚如何让Android Studio使用我的Android.mk 找到正确的makefile变量。希望这会有所帮助。
股票Android Studio将完全忽略任何自定义
您创建的Android.mk文件,而不是自动生成自己的文件。
要更正此问题,您必须先破解 build.gradle
项目的脚本,位于project/app/build.gradle
。
如果需要,您可能会破解顶级build.gradle。
这是我的黑客build.gradle。我建立在Windows机器上,所以我 仅针对Windows攻击它。如果您使用OSX,请取消注释行 或Linux。
<强>项目/应用/的build.gradle:强>
//import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.sample.app"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//ENABLE CUSTOM ANDROID.MK >>
sourceSets.main.jni.srcDirs= [] //Disable automatic ndk-build.
sourceSets.main.jniLibs.srcDir 'src/main/libs'
//Call regular ndk-build script from app directory
task ndkBuild(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd()
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task cleanNative(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd(), 'clean'
}
clean.dependsOn cleanNative
}
//ENABLE CUSTOM ANDROID.MK <<
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:7.5.0'
}
//ENABLE CUSTOM ANDROID.MK >>
def getNdkDir() {
if (System.env.ANDROID_NDK_ROOT != null)
return System.env.ANDROID_NDK_ROOT
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkdir = properties.getProperty('ndk.dir', null)
if (ndkdir == null)
throw new GradleException("NDK location not found. Define location with ndk.dir in the local.properties file")
return (ndkdir)
}
def getNdkBuildCmd() {
def ndkbuild = getNdkDir() + "/ndk-build.cmd"
// def ndkbuild = getNdkDir() + "/ndk-build"
// if (Os.isFamily(Os.FAMILY_WINDOWS))
// ndkbuild += ".cmd"
return ndkbuild
}
//ENABLE CUSTOM ANDROID.MK <<
现在我可以创建我的多库Android.mk。这构建 两个静态链接库,然后构建最终的动态链接 前两个库和链接。涉及的目录 是:
<强>目录:强>
project/
app/
build.gradle
src/
main/
java/
jni/
Android.mk
include/
libmp3lame/
MiniMp3/
mp3_jni.c
mpglib/
<强> Android.mk:强>
TOP_PATH := $(call my-dir)
LOCAL_PATH := $(TOP_PATH)/libmp3lame
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := libmp3lame
LOCAL_SRC_FILES := \
bitstream.c \
...
version.c
include $(BUILD_STATIC_LIBRARY)
MY_LOCAL_STATIC_LIBRARIES += libmp3lame
LOCAL_PATH := $(TOP_PATH)/mpglib
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_C_INCLUDES += $(TOP_PATH)/libmp3lame
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := mpglib
LOCAL_SRC_FILES := \
common.c \
...
tabinit.c
include $(BUILD_STATIC_LIBRARY)
MY_LOCAL_STATIC_LIBRARIES += mpglib
LOCAL_PATH := $(TOP_PATH)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := Mp3
LOCAL_STATIC_LIBRARIES := $(MY_LOCAL_STATIC_LIBRARIES)
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
./mp3_jni.c
include $(BUILD_SHARED_LIBRARY)
您需要调整Android.mk。
答案 2 :(得分:0)
从Android Studio 4.0开始,AGP(Android Gradle插件)支持一种称为Prefab的新机制。这使用了特别准备的AAR,可以像其他外部库一样在项目依赖项中列出该AAR,并且可以获得从CMake或ndk-build链接到该库所必需的头和构建标志。
这类似于@alijandro的exploded-aar approach,但得到官方支持,并且所需的样板更少。例如。您只需要
find_package(first REQUIRED CONFIG)
target_link_libraries(app first::libfirst)