Android Studio - App + NDK模块库

Wil*_*tte 5 c android module static-libraries android-ndk

花了几个小时寻找我的问题的解决方案并浏览各种论坛(包括这个论坛)后,我终于决定问我的问题,希望它在其他地方没有完全回答.

我正在尝试构建一个非常复杂的架构:

  • 我有C源代码,我在分离静态库(.a)编译
  • 我在模块库中通过JNI使用它们
  • 我想在app项目中使用这个库.

我首先成功完成了以下测试 - 我已经设法创建了一个没有NDK的模块库,并使用该应用程序进行编译. - 我还设法直接在应用程序中使用静态库和JNI

我没有通过以下步骤: - 模块内部的JNI和调用模块类的app的组合不起作用.

我认为问题在于aar的包含,因为当aar位于库构建/输出目录中时,我无法在我的应用程序的构建目录中找到爆炸的aar.此外,所有以前的测试(包括使用JNI都是成功的).

我没有使用实验模型,因为它是实验性的,静态库存在已知的局限性.

我的项目结构是:

- App
    - src
        - main
            - java
                - activity  
- bar
    - src
        - main
            - java
                - class
            - jni
                - include
                    - *.h
                - libs
                    - abis...
                        - libmod1.a
                        - libmod2.a
                Android.mk
                Application.mk
                bar.c
                bar.h
Run Code Online (Sandbox Code Playgroud)

app build.gradle看起来像这样:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"

    defaultConfig {
        applicationId "com.test.foo"
        minSdkVersion 10
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    buildTypes {

        release {
            debuggable          false
            jniDebuggable       false
            minifyEnabled       false
        }
        unsigned {
            debuggable          false
            jniDebuggable       false
            minifyEnabled       false
        }
        debug {
            debuggable          true
            jniDebuggable       true
            minifyEnabled       false
        }
    }


    productFlavors {
        x86 {
            ndk {
                abiFilter "x86"
            }
        }
        mips {
            ndk {
                abiFilter "mips"
            }
        }
        armv7 {
            ndk {
                abiFilter "armeabi-v7a"
            }
        }
        arm {
            ndk {
                abiFilter "armeabi"
            }
        }
        fat
    }

    project.ext.versionCodes = ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, 'x86':8, 'x86_64':9]

    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionCodeOverride =
                    project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + defaultConfig.versionCode
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
    compile project( ":bar" )
}
Run Code Online (Sandbox Code Playgroud)

模块build.gradle看起来像这样:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "module"
        }
    }
    buildTypes {

        release {
            debuggable      false
            jniDebuggable   false
            minifyEnabled   false
        }
        unsigned {
            debuggable      false
            jniDebuggable   false
            minifyEnabled   false
        }
        debug {
            debuggable      true
            jniDebuggable   true
            minifyEnabled   false
        }
    }

    productFlavors {
        x86 {
            ndk {
                abiFilter "x86"
            }
        }
        mips {
            ndk {
                abiFilter "mips"
            }
        }
        armv7 {
            ndk {
                abiFilter "armeabi-v7a"
            }
        }
        arm {
            ndk {
                abiFilter "armeabi"
            }
        }
        fat
    }
    sourceSets.main {
        jniLibs.srcDir 'src/main/libs'
        jni.srcDirs     = []
    }

    task ndkBuild(type: Exec) {
        commandLine android.ndkDirectory.getAbsolutePath()+'/ndk-build', '-C', file('src/main').absolutePath
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
Run Code Online (Sandbox Code Playgroud)

模块jni目录中的我的Android.mk是:LOCAL_PATH:= $(call my-dir)

#### Mod1
include $(CLEAR_VARS)
LOCAL_MODULE            := mod1
LOCAL_SRC_FILES         := libs/$(TARGET_ARCH_ABI)/libmod1.a
include $(PREBUILT_STATIC_LIBRARY)

#### Mod2
include $(CLEAR_VARS)
LOCAL_MODULE            := pxnav
LOCAL_SRC_FILES         := libs/$(TARGET_ARCH_ABI)/libmod2.a
LOCAL_STATIC_LIBRARIES  := pxfd
include $(PREBUILT_STATIC_LIBRARY)

##### Parser
include $(CLEAR_VARS)
LOCAL_MODULE            := module
LOCAL_C_INCLUDES        := $(LOCAL_PATH)/include
LOCAL_LDLIBS            += -landroid -llog
LOCAL_SRC_FILES         := bar.c
LOCAL_STATIC_LIBRARIES  := mod1 mod2
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

Ale*_*ohn 0

我找到了类似任务的简单解决方法:我只需设置jniLibs.srcDir应用程序模块即可。现在,我不再依赖分解aar来获取.so文件。顺便说一句,当您决定切换到实验性插件(以使用本机调试、C++ 语法突出显示和交叉引用以及其他细节)时,我们邀请您检查在 ndk{} DSL 中定义 LOCAL_SRC_FILES