当前位置: 首页 > 知识库问答 >
问题:

Android Studio中的JNI和Gradle

郎泰平
2023-03-14

我正在尝试添加本机代码到我的应用程序。我在../main/jni中拥有与在Eclipse项目中一样的所有内容。我已将ndk.dir=...添加到我的local.properties中。我还没有做任何其他的事情(我不确定还需要做什么,所以如果我错过了什么,请告诉我)。当我尝试构建时,会出现以下错误:

Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
    /Users/me/android-ndk-r8e/ndk-build NDK_PROJECT_PATH=null 
APP_BUILD_SCRIPT=/Users/me/Project/app/build/ndk/debug/Android.mk APP_PLATFORM=android-19 
NDK_OUT=/Users/me/Project/app/build/ndk/debug/obj 
NDK_LIBS_OUT=/Users/me/Project/app/build/ndk/debug/lib APP_ABI=all

  Error Code:
    2
  Output:
    make: *** No rule to make target `/Users/me/Project/webapp/build/ndk/debug//Users/me/Project/app/src/main/jni/jni_part.cpp',
 needed by `/Users/me/Project/app/build/ndk/debug/obj/local/armeabi-v7a/objs/webapp//Users/me/Project/app/src/main/jni/jni_part.o'.  
Stop.

我需要做什么?

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include .../OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := native_part
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8

共有1个答案

鞠自明
2023-03-14

在努力避免实验性和坦率地说受够了NDK和它的所有黑客,我很高兴的是,2.2.x的Gradle构建工具出来了,现在它只是工作。关键是externalnativebuild并将ndkbuild路径参数指向android.mk或将ndkbuild更改为cmake并将路径参数指向cmakelists.txt生成脚本。

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

        externalNativeBuild {
            cmake {
                cppFlags '-std=c++++11'
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE',
                        '-DANDROID_CPP_FEATURES=exceptions rtti'
            }
        }
    }

    externalNativeBuild {
        cmake {
             path 'src/main/jni/CMakeLists.txt'
        }
        //ndkBuild {
        //   path 'src/main/jni/Android.mk'
        //}
    }
}

要了解更多细节,请查看Google关于添加本机代码的页面。

正确设置后,您可以./gradlew installdebug然后离开。您还需要注意的是,NDK正在向clang移动,因为现在Android NDK中不推荐使用gcc。

其他答案确实指出了防止自动创建Android.mk文件的正确方法,但它们没有走出更好地与Android Studio集成的额外一步。我添加了从源代码处实际清理和构建的能力,而不需要转到命令行。您的local.properties文件需要具有ndk.dir=/path/to/ndk

apply plugin: 'com.android.application'

android {
    compileSdkVersion 14
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.example.application"
        minSdkVersion 14
        targetSdkVersion 14

        ndk {
            moduleName "YourModuleName"
        }
    }

    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
        jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
    }

    task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
        def ndkDir = android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                '-j', Runtime.runtime.availableProcessors(),
                'all',
                'NDK_DEBUG=1'
    }

    task cleanNative(type: Exec, description: 'Clean JNI object files') {
        def ndkDir = android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                'clean'
    }

    clean.dependsOn 'cleanNative'

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

dependencies {
    compile 'com.android.support:support-v4:20.0.0'
}

src/main/jni目录假定项目的标准布局。它应该是build.gradle文件位置与jni目录的相对关系。

还要检查此堆栈溢出答案。

这是真正重要的,你的分级版本和一般设置是正确的。如果你有一个较老的项目,我强烈建议你用最新的Android Studio创建一个新的项目,看看谷歌认为标准项目是什么。另外,请使用gradlew。这可以保护开发人员免受gradle版本不匹配的影响。最后,必须正确配置gradle插件。

然后你问gradle插件的最新版本是什么?检查工具页面并相应地编辑版本。

// Top-level build file where you can add configuration options common to all sub-projects/modules.

// Running 'gradle wrapper' will generate gradlew - Getting gradle wrapper working and using it will save you a lot of pain.
task wrapper(type: Wrapper) {
    gradleVersion = '2.2'
}

// Look Google doesn't use Maven Central, they use jcenter now.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

确保gradle wrapper生成gradlew文件和gradle/wrapper子目录。这是个大陷阱。

这已经出现了很多次,但是android.ndkdirectory是在1.1之后获取文件夹的正确方法。将Gradle项目迁移到1.0.0版本。如果你使用的是一个试验性的或古老的插件版本,你的里程可能会有所不同。

 类似资料:
  • 我正在从eclipseADT迁移到android Studio,我可以从Eclipse使用相同的android SDK吗?

  • 应用程序 SlidingMenu(源文件) SlidingMenu-Maps-Support(源文件) 这里有一个链接,看看我的意思。 这就是我得到的错误。 谢谢! 编辑1:不要紧!我又回到月食了!Android Studio还没有为真正的项目开发做好准备。

  • 我想做一个应用程序,使用谷歌翻译API。自从我添加了 我的构建中的依赖项。gradle我有个错误: 现在必须显式声明注释处理器。发现编译类路径上的以下依赖项包含注释处理器。请将它们添加到annotationProcessor配置中。-自动值-1.2。jar(com.google.auto.value:auto-value:1.2)或者,设置android。defaultConfig。javaCom

  • 长话短说:我有一个可执行的jar,它调用,它依赖于。我得到了非常可怕的。 这个答案非常接近,但根据我的经验,它不能解决问题。即使在中指定了dll所在的文件夹,它也不会工作。我还必须更改Windows环境变量。事实上,Windows上默认的似乎是。 有什么“漂亮”的方法可以解决这个问题吗?我想为Windows构建一个安装程序,我想知道如何处理这个问题,这样最终用户就不必做任何手动工作。 编辑: 我实

  • 问题内容: 所以我在C中使用了Java本机接口的以下代码,但是我想将其转换为C ++,但不确定如何。 Java程序: JNI与C和C ++交互的区别是什么?任何帮助是极大的赞赏。 谢谢,皮特 问题答案: 我曾经有一本书《EssentialJNI》。虽然它有些过时,但今天仍然可以使用。 如果我没记错的话,在C语言中,Java构造只是指针。因此,在您的代码中,“ ”是取消引用指针,以使您可以访问基础方

  • 在我的JNI项目中,我需要向java客户机添加事件/回调,该客户机将从本机库接收此事件。在c中,我这样做: 基于对话框: 在控制台应用程序中,它就像 设置此事件回调后,库将向给定函数触发此事件。我可以在本机库中设置函数和回调,但我不知道如何将其发送到java应用程序。任何人都可以给我一个提示,如何使用JNI处理这个问题?