Android的工作室 - 应用+ NDK模块库 [英] Android Studio - App + NDK Module library

查看:173
本文介绍了Android的工作室 - 应用+ NDK模块库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

花几个小时寻找一个解决我的问题和浏览各种论坛(包括本),我终于决定要问我的问题,希望它尚未完全别处回答后。

我想建立一个pretty复杂的架构:


  • 我有我编译分离静态库(.a)中
  • C源码
  • 我通过JNI使用它们的模块中库

  • 我想在一个应用程序项目中使用这个库。

我第一次成功地做了以下测试
- 我已经成功地使一个模块库,而不NDK和应用程序进行编译。
- 我也设法使用静态库和JNI直接在应用程序,但

我通过以下几个步骤失败:
- JNI的模块和应用程序调用的模块类中的组合不工作

我认为这个问题是与包括AAR的,因为我无法找到我的应用程序的生成目录的爆炸-AAR而​​AAR是库构建/输出目录。此外,所有的previous测试(包括使用
JNI是成功的)。

我不使用的实验模型,因为它是实验性和存在的一些已知静态库的限制。

我的项目的结构是:

   - 应用
     - SRC
         - 主
             - java的
                 - 活动
- 酒吧
     - SRC
         - 主
             - java的
                 - 类
             - JNI
                 - 包括
                    - *。H
                 - 库
                     - ABIS ...
                         - libmod1.a
                         - libmod2.a
                Android.mk
                Application.mk
                bar.c
                bar.h

该应用程序的build.gradle看起来是这样的:

 应用插件:'com.android.application安卓{
    compileSdkVersion 23
    buildToolsVersion23.0.0    defaultConfig {
        的applicationIDcom.test.foo
        10的minSdkVersion
        targetSdkVersion 23
        版本code 1
        的versionName1.0
    }    buildTypes {        发布 {
            调试的假
            jniDebuggable假
            minifyEnabled假
        }
        无符号{
            调试的假
            jniDebuggable假
            minifyEnabled假
        }
        调试{
            调试的真
            jniDebuggable真
            minifyEnabled假
        }
    }
    productFlavors {
        86 {
            NDK {
                abiFilter86
            }
        }
        MIPS {
            NDK {
                abiFilterMIPS
            }
        }
        {的ARMv7
            NDK {
                abiFilterarmeabi-V7A
            }
        }
        手臂{
            NDK {
                abiFilterarmeabi
            }
        }
        脂肪
    }    project.ext.version codeS = ['armeabi':1,​​'armeabi-V7A:2,arm64-V8A':3,'MIPS':5,MIPS64:6,'86':8 x86_64的':9]    android.applicationVariants.all {变种 - >
        variant.outputs.each {输出 - >
            output.version codeOverride =
                    project.ext.version codes.get(output.getFilter(com.android.build.OutputFile.ABI),0)* 1000000 + defaultConfig.version code
        }
    }
}依赖{
    编译文件树(导演:'库',包括:['的* .jar,*。AAR'])
    编制项目(:巴)
}

该模块的build.gradle看起来是这样的:

 应用插件:'com.android.library安卓{
    compileSdkVersion 23
    buildToolsVersion23.0.0    defaultConfig {
        10的minSdkVersion
        targetSdkVersion 23
        版本code 1
        的versionName1.0        NDK {
            MODULENAME模块
        }
    }
    buildTypes {        发布 {
            调试的假
            jniDebuggable假
            minifyEnabled假
        }
        无符号{
            调试的假
            jniDebuggable假
            minifyEnabled假
        }
        调试{
            调试的真
            jniDebuggable真
            minifyEnabled假
        }
    }    productFlavors {
        86 {
            NDK {
                abiFilter86
            }
        }
        MIPS {
            NDK {
                abiFilterMIPS
            }
        }
        {的ARMv7
            NDK {
                abiFilterarmeabi-V7A
            }
        }
        手臂{
            NDK {
                abiFilterarmeabi
            }
        }
        脂肪
    }
    sourceSets.main {
        jniLibs.srcDir'的src / main /库
        jni.srcDirs = []
    }    任务ndkBuild(类型:执行){
        命令行android.ndkDirectory.getAbsolutePath()+'/ NDK的构建,-C,文件(钢骨混凝土/主')。absolutePath
    }    tasks.withType(JavaCompile){
        compileTask - > compileTask.dependsOn ndkBuild
    }
}依赖{
    编译文件树(导演:'库',包括:['的* .jar'])
}

我的模块JNI目录内Android.mk是:
    LOCAL_PATH:= $(叫我-DIR)

  #### MOD1
包括$(CLEAR_VARS)
LOCAL_MODULE:= MOD1
LOCAL_SRC_FILES:=库/ $(TARGET_ARCH_ABI)/libmod1.a
包括$(preBUILT_STATIC_LIBRARY)#### MOD2
包括$(CLEAR_VARS)
LOCAL_MODULE:= pxnav
LOCAL_SRC_FILES:=库/ $(TARGET_ARCH_ABI)/libmod2.a
LOCAL_STATIC_LIBRARIES:= pxfd
包括$(preBUILT_STATIC_LIBRARY)#####分析器
包括$(CLEAR_VARS)
LOCAL_MODULE:=模块
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/包括:
LOCAL_LDLIBS + = -landroid -llog
LOCAL_SRC_FILES:= bar.c
LOCAL_STATIC_LIBRARIES:= MOD1 MOD2
包括$(BUILD_SHARED_LIBRARY)


解决方案

我找到了类似的任务简单的解决方法:我简单地设置 jniLibs.srcDir 应用模块。现在,我不依赖于炸响在 AAR ,以获得地方在的.so 文件。顺便说一句,当你决定要切换到的实验的插件(使用本机调试,C ++语法高亮和交叉引用等细微),你被邀请参加检查的 define在NDK {} DSL LOCAL_SRC_FILES

After spending hours and hours searching for a solution to my problem and browsing the various forums (including this one) i finally decided to ask my question, hoping that it has not been fully answered elsewhere.

I'm trying to build a pretty complex architecture :

  • I have C sources that i compile in separates static libraries (.a)
  • I use them via JNI in a module Library
  • I want to use this library in an app project.

I first successfully did the following tests - I already managed to make a module library without NDK and compile it with the app. - I also managed to use the static libraries and JNI directly in the app but

I am failing with the following step : - The combination of JNI inside the module and app calling the classes of the module doesn't work.

I think the problem is with the include of the aar, because I can't find the exploded-aar in the build directory of my app while the aar is in the library build/outputs directory. Besides, all the previous tests (including the use of JNI were successful).

I'm not using the experimental model because it is experimental and there are known limitations with static libraries.

The structure of my project is :

- 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

The app build.gradle looks like this :

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" )
}

The module build.gradle looks like this :

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'])
}

My Android.mk inside the module jni directory is : 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)

解决方案

I found an easy workaround for similar task: I simply set jniLibs.srcDir for the app module. Now I don't depend on exploding the aar to get the .so files in place. BTW, when you decide to switch to experimental plugin (to use native debugging, C++ syntax highlighting and cross-references and other niceties), you are invited to check define LOCAL_SRC_FILES in ndk{} DSL.

这篇关于Android的工作室 - 应用+ NDK模块库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆