如何使用Android插件为gradle 2.3.1在Android Studio中找到打包在AAR中的jni库?

Y.Y*_*ina 5 android

我的项目必须使用 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库?

spa*_*lug 0

对于使用 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)