我的项目必须使用 AAR 作为依赖项。AAR 打包了一些类和一个 jni 库 (eglibdemo.so)。jni 库在我的项目中用作 LOCAL_SHARED_LIBRARIES。
对于gradle 2.2.3的Android插件,我采取以下两种方式:
1.手动解压AAR,将libdemo.so放在Android.mk相关目录下:
###########################prebuild libdemo.so##############################
include $(CLEAR_VARS)
LOCAL_MODULE := libdemo LOCAL_SRC_FILES := libdemo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include
$(PREBUILT_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
2.AAR 在 build/intermediate 中未打包。所以我在Android.mk中设置了libdemo.so的路径:
###########################prebuild libdemo.so##############################
include $(CLEAR_VARS)
LOCAL_MODULE := libdemo
AAR_LIB_PATH = $(LOCAL_PATH)/../../../build/intermediates/exploded-aar/vm/jni/armeabi
LOCAL_SRC_FILES := $(AAR_LIB_PATH)/libdemo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
但是对于gradle 2.3.1的Android插件,规则改变了吗?
构建缓存:存储 Android 插件在构建项目时生成的某些输出(例如未打包的 AAR 和 pre-dexed 远程依赖项)。
我指定了一个相对于 gradle.properties 文件的路径。
android.buildCacheDir=buildcache
Run Code Online (Sandbox Code Playgroud)
它有效,我可以看到缓存,但我找不到 libdemo.so 直接构建缓存:
我现在不能使用 WAY 2。有没有更方便的方法来链接jni库?
对于使用 Android NDK 的项目,使用 Gradle 实验版本在应用程序中实现 JNI 功能会更容易。
*.so
解压AAR包后即可访问库文件。以下是一个示例 gradle 函数,用于将 AAR 提取到保存*.so
文件的相应构建路径:
task extractSo(type: Copy) {
from zipTree("${project.rootDir}/libraries/name-of-aar-package.aar")
into "${project.rootDir}/libraries/"
include "jni/**/name-of-so-library.so"
}
Run Code Online (Sandbox Code Playgroud)
在整个项目的extractSo
基础文件中定义任务。build.gradle
要使用 Gradle 实验版本,您还必须在基本build.gradle
文件中定义 Gradle 实验的类路径,如下所示:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.9.0'
}
}
Run Code Online (Sandbox Code Playgroud)
要调用该extractSo
任务,您必须在需要该函数的项目模块的 build.gradle 文件中定义对此函数的依赖关系。以下是执行此操作的一些示例代码:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 25
buildToolsVersion = "25.0.2"
defaultConfig.with {
applicationId = "com.my.sample.package.ndkapp"
minSdkVersion.apiLevel = 19
targetSdkVersion.apiLevel = 24
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-android.txt'))
}
}
android.ndk {
moduleName = "nativeclass_jni"
cppFlags.add("-std=c++11")
cppFlags.add("-I" + file("src/main/jni").absolutePath)
// Add the necessary headers required in cpp code.
cppFlags.add("-I" + file("${project.rootDir}/libraries/headers").absolutePath)
stl = "gnustl_shared"
// Add the necessary project .so files for all architectures.
ldFlags.add("-L" + file("${project.rootDir}/libraries/jni/arm64-v8a").absolutePath)
ldFlags.add("-L" + file("${project.rootDir}/libraries/jni/armeabi-v7a").absolutePath)
ldFlags.add("-L" + file("${project.rootDir}/libraries/jni/x86").absolutePath)
ldLibs.addAll(["log", "android", "EGL", "GLESv2"])
// Specific the particular .so files this sample links against.
ldLibs.add("name-of-so-library")
}
android.productFlavors {
create ("fat") {
// This sample builds all architectures by default. Note that if you
// only want to build for a specific architecture, you need to
// remove the appropriate lines below. You also need to remove the
// .so files from the apk using
// "packagingOptions {exclude('lib/armeabi-v7a/*')}" in the android
// section.
ndk.abiFilters.add("arm64-v8a")
ndk.abiFilters.add("armeabi-v7a")
ndk.abiFilters.add("x86")
}
}
}
dependencies {
// specify any Android java modules this project depends on
// For example:
// compile files('libs/android-support-v4.jar')
}
// Extract the *.so libraries packaged in AAR files.
build.dependsOn(':extractSo')
Run Code Online (Sandbox Code Playgroud)
为了确保您的 Java 代码可以访问 *.so 文件中的本机函数和本机 Android 代码,您现在必须在主 Activity 中加载该库,如下所示:
static {
// Loading your native code module
System.loadLibrary("nativeclass_jni");
// Loading your extracted *.so library
System.loadLibrary("name-of-so-library");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1223 次 |
最近记录: |