JNI และ Gradle ใน Android Studio

ฉันกำลังพยายามเพิ่มโค้ดเนทิฟให้กับแอปของฉัน ฉันมีทุกอย่างใน ../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.

ฉันต้องทำอย่างไร?

Android.mk:

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

comment
มีชุดข้อความที่นี่ซึ่งอาจให้ข้อมูลเชิงลึกเล็กๆ น้อยๆ แก่คุณ: groups .google.com/forum/#!topic/adt-dev/-GbnrQA8f7M   -  person Scott Barta    schedule 13.01.2014


คำตอบ (6)


Gradle Build Tools 2.2.0+ - NDK ที่ใกล้เคียงที่สุดที่เคยถูกเรียกว่า 'เวทมนตร์'

ในการพยายามหลีกเลี่ยงการทดลองและเบื่อหน่ายกับ NDK และแฮ็กเกอร์ทั้งหมดของมัน ฉันดีใจที่ Gradle Build Tools 2.2.x ออกมา และตอนนี้มันก็ใช้งานได้แล้ว กุญแจสำคัญคือ 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 กำลังย้ายไปที่เสียงดังกราวเนื่องจาก gcc เลิกใช้แล้วใน Android NDK

การผสานรวมการทำความสะอาดและสร้าง Android Studio - เลิกใช้แล้ว

คำตอบอื่น ๆ ชี้ให้เห็นวิธีที่ถูกต้องในการป้องกันการสร้างไฟล์ 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

Gradle - สำหรับผู้ที่มีปัญหา

ตรวจสอบคำตอบของ Stack Overflow นี้ด้วย

สิ่งสำคัญอย่างยิ่งคือเวอร์ชันการไล่ระดับและการตั้งค่าทั่วไปของคุณถูกต้อง หากคุณมีโปรเจ็กต์เก่า ฉันขอแนะนำให้สร้างโปรเจ็กต์ใหม่ด้วย Android Studio เวอร์ชันล่าสุด และดูว่า Google พิจารณาอะไรเป็นโปรเจ็กต์มาตรฐาน นอกจากนี้ ให้ใช้ gradlew สิ่งนี้จะช่วยปกป้องนักพัฒนาจากเวอร์ชัน gradle ที่ไม่ตรงกัน สุดท้ายนี้ ปลั๊กอิน gradle จะต้องได้รับการกำหนดค่าอย่างถูกต้อง

และคุณถามว่าปลั๊กอิน gradle เวอร์ชันล่าสุดคืออะไร? ตรวจสอบหน้าเครื่องมือและแก้ไขเวอร์ชันตามนั้น

ผลิตภัณฑ์ขั้นสุดท้าย - /build.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 นี่คือ gotcha ใหญ่

ndkDirectory

เกิดขึ้นหลายครั้ง แต่ android.ndkDirectory เป็นวิธีที่ถูกต้องในการรับโฟลเดอร์หลังจาก 1.1 การย้ายโครงการ Gradle ไปเป็นเวอร์ชัน 1.0.0< /ก>. หากคุณใช้ปลั๊กอินเวอร์ชันทดลองหรือเวอร์ชันเก่า ระยะทางของคุณอาจแตกต่างกันไป

person Cameron Lowell Palmer    schedule 01.11.2014
comment
การปรับแต่งอย่างหนึ่งที่ฉันต้องทำ: กำหนดงานที่อยู่นอกบล็อก Android มิฉะนั้น gradle จะบ่น - person Utkarsh Sinha; 25.12.2014
comment
คุณสามารถใช้ def ndkDir = android.plugin.ndkFolder เป็นวิธีที่ง่ายกว่าในการอ้างอิงถึงปลั๊กอิน Android - person Ben Lings; 02.01.2015
comment
@UtkarshSinha ที่ดูเหมือนผิด คุณสามารถยืนยันได้ว่าคุณกำลังใช้งานการไล่ระดับล่าสุดหรือไม่? - person Cameron Lowell Palmer; 02.01.2015
comment
ฉันเห็นปัญหาเดียวกันกับ @UtkarshSinha หรืออะไรที่คล้ายกัน งานจะถูกขีดเส้นใต้ด้วยสีเทาและข้อความต่อไปนี้จะปรากฏขึ้น: ไม่สามารถอนุมานประเภทอาร์กิวเมนต์ได้ Gradle เป็นเวอร์ชันล่าสุด (2.2.1) และฉันเชื่อว่าปัญหาอยู่ที่อื่นเช่นเดียวกับใน sourceSets.main สัญลักษณ์ jni และ jniLibs ถูกขีดเส้นใต้ด้วยข้อความ ไม่สามารถแก้ไขสัญลักษณ์ได้ เมื่อฉันย้ายงานนอกบล็อก Android จะไม่แสดงข้อผิดพลาด แต่ฉันไม่คิดว่านี่จะถูกต้อง - person Oliver Hausler; 11.01.2015
comment
คุณแน่ใจหรือว่าคุณกำลังใช้การไล่ระดับที่คุณคิดว่าเป็น? - person Cameron Lowell Palmer; 11.01.2015
comment
@CameronLowellPalmer ฉันไม่เข้าใจว่าคุณทำอะไรที่นี่ ไฟล์ไหนควรแก้ไข และควรเพิ่มไฟล์อะไร? คุณช่วยดูห้องสมุดของฉันที่นี่ได้ไหม: github.com/AndroidDeveloperLB/AndroidJniBitmapOperations ? ฉันพยายามทำสิ่งที่คุณเขียนแล้ว แต่ฉันคิดว่าบางสิ่งที่คุณเขียนจำเป็นต้องเปลี่ยนแปลงในกรณีของฉัน - person android developer; 16.01.2015
comment
@androiddeveloper เมื่อฉันแก้ไข gradle-wrapper.properties เพื่อใช้ gradle-2.2-all.zip ทุกอย่างเป็นไปด้วยดี - person Cameron Lowell Palmer; 16.01.2015
comment
@CameronLowellPalmer ฉันไม่เข้าใจสิ่งที่คุณเขียน คุณช่วยโพสต์ไปที่ Github ได้ไหมว่าควรเปลี่ยนแปลงอะไรบ้าง? - person android developer; 16.01.2015
comment
@androiddeveloper ตรวจสอบคำขอดึงของคุณ ฉันได้กระทำสองครั้ง - person Cameron Lowell Palmer; 16.01.2015
comment
@UtkarshSinha ฉันจะตรวจสอบการอัปเดตที่ฉันทำกับคำตอบเพื่อวัตถุประสงค์ในการชี้แจง ซึ่งอาจช่วยให้คุณกำหนดค่าโปรเจ็กต์ได้อย่างถูกต้อง - person Cameron Lowell Palmer; 16.01.2015
comment
@GregEnnis ฉันจะดีใจที่ได้คะแนนสูงสุด :) - person Cameron Lowell Palmer; 23.01.2015
comment
ฉันมีปัญหา: android.plugin.ndkFolder ส่งคืน 'null' ฉันจะกำหนดเส้นทาง ndk ของฉันได้อย่างไร ขอบคุณ - person jmrodrigg; 27.01.2015
comment
แก้ไขแล้ว: ฉันไม่ได้เพิ่ม ndk.dir ใน local.properties ตอนนี้ฉันกำลังจัดการกับปัญหา การสนับสนุน NDK ปัจจุบันเลิกใช้แล้ว - person jmrodrigg; 27.01.2015
comment
นั่นไม่ใช่ปัญหา นั่นเป็นคำเตือนเชิงข้อมูล ในที่สุด Google ก็อาจปรับปรุงการรองรับ NDK ได้ - person Cameron Lowell Palmer; 27.01.2015
comment
ขอบคุณ คุณพูดถูก ปัญหาอยู่ที่อื่น ฉันเปิดใช้งาน stacktrace และตระหนักว่าฉันต้องเรียกใช้ 'ndk-build.cmd' ฉันลืมใส่นามสกุล ตอนนี้มันทำงานได้อย่างสมบูรณ์แบบ - person jmrodrigg; 27.01.2015
comment
ใช่. ตอนนี้ฉันกำลังมองหาบางอย่างเพื่อเรียกใช้ commandLine ที่แตกต่างกันขึ้นอยู่กับระบบปฏิบัติการ... มีแนวคิดใดบ้าง - person jmrodrigg; 28.01.2015
comment
@CameronLowellPalmer ขอบคุณ - person jmrodrigg; 29.01.2015
comment
@jmrodrigg ไม่มีอะไรอยู่ในใจ ข้ามแพลตฟอร์มนั้นยาก ปัญหาใหญ่ที่สุดที่คุณจะต้องเผชิญคือการค้นหาเครื่องมือที่จำเป็น ฉันคิดว่าในบางจุดจำเป็นต้องมี README และการแทรกแซงจากผู้ใช้ - person Cameron Lowell Palmer; 29.01.2015
comment
@jmrodrigg คุณสามารถใช้ org.apache.tools.ant.taskdefs.condition.Os เหมือนที่ฉันทำในส่วนสำคัญนี้: gist.github.com/ph0b/9e59058ac59cac104398 นอกจากนี้ หากมีการเพิ่ม ndk-build ให้กับเส้นทางของผู้ใช้ ก็ไม่จำเป็นต้องระบุตำแหน่งของเส้นทางนั้น - person ph0b; 27.04.2015
comment
:) เมื่อคุณพบว่าตัวเองใช้มด คุณไม่ล้มเหลวใช่ไหม? - person Cameron Lowell Palmer; 28.04.2015
comment
ฉันต้องเพิ่ม def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.ndkFolder เพื่อให้มันใช้งานได้ - person SztupY; 15.06.2015
comment
ขอบคุณ SztupY! AStudio build 141.2006197 บ่นว่าไม่พบปลั๊กอิน ข้อเสนอแนะของคุณแก้ไขปัญหานั้นได้! - person Zoccadoum; 17.06.2015
comment
+1 ถึง SztupY เช่นกัน ฉันใช้ปลั๊กอิน android-gradle 1.2.3 & gradle 2.4, android.plugin.ndkFolder ผลลัพธ์ไม่พบคุณสมบัติปลั๊กอิน ฉันกำลังสร้างห้องสมุดดังนั้น Plugins.getPlugin('com.android.library').sdkHandler.ndkFolder ช่วยได้ @SztupY คุณหาเอกสารสำหรับปลั๊กอินนั้นได้จากที่ไหนในโลก? คุณรู้ได้อย่างไรว่ามีคุณสมบัติอะไรบ้างในนั้น? - person Some Noob Student; 20.06.2015
comment
@SomeNoobStudent ฉันแค่ค้นหาใน Google และพบหัวข้อที่คล้ายกันที่อื่น สิ่งที่พวกเขาเขียนไม่ได้ผลเลย แต่บรรทัดนี้มีประโยชน์ที่นี่ - person SztupY; 20.06.2015
comment
@CameronLowellPalmer - ใช่บรรทัดคำสั่ง (ndk_build.sh) ทำงานได้ดี แต่ gradle build บ่นจนกว่าฉันจะเพิ่มคำแนะนำของ SztupY - person Zoccadoum; 23.06.2015
comment
@CameronLowellPalmer ฉันจะเปลี่ยนโซลูชันนี้เพื่อใช้ 'NDK_DEBUG=1' สำหรับประเภทบิลด์การดีบักและ 'NDK_DEBUG=0' สำหรับประเภทบิลด์รีลีสได้อย่างไร - person DeathlessHorsie; 26.07.2015
comment
@DeathlessHorsie วิธีหนึ่งคือการสร้างงานสองงานแยกกัน คุณสามารถตั้งชื่องานเหล่านั้นว่า buildNativeRelease และ buildNativeDebug เป็นต้น - person Cameron Lowell Palmer; 27.07.2015
comment
@CameronLowellPalmer ใช่ ฉันลองแล้ว ฉันลองใช้รหัสนี้: Tasks.whenTaskAdded { งาน -› if(task.getName().contains(generateReleaseSources)) { task.dependsOn buildNativeRelease } else if(task.getName().contains(generateDebugSources)) { task.dependsOn buildNativeDebug } } ฉันเห็นปัญหาสองประการ: 1. เมื่อฉันกำหนดค่าไลบรารีเป็น Debug ไลบรารีก็จะรันงานรีลีสด้วย 2. เมื่อฉันสร้างหลังจากเปลี่ยนประเภทบิลด์ มันจะไม่คอมไพล์โค้ดเนทีฟอีกครั้ง ดังนั้นไฟล์ debug/release *.so จึงยังคงอยู่ บางครั้งมันก็สร้างโค้ดเนทีฟขึ้นมาใหม่ - person DeathlessHorsie; 27.07.2015
comment
@DeathlessHorsie ลองสิ่งนี้: Tasks.whenTaskAdded { Task -› if (task.name == 'compileDebugNdk') { Task.dependsOn buildNativeDebug } } แจ้งให้เราทราบหากใช้งานได้ - person Cameron Lowell Palmer; 28.07.2015
comment
@CameronLowellPalmer การทำให้คอมไพล์ DebugNdk ขึ้นอยู่กับ buildNativeDebug ดูเหมือนจะเป็นตัวเลือกที่ดีกว่า GenerateDebugSources อย่างไรก็ตาม มันไม่ได้แก้ปัญหาของฉัน 1. ดูเหมือนว่าจะเป็นข้อจำกัดของ android studio/gradle มีตัวเลือกในการสร้างโมดูลเฉพาะจากเมนูบริบทในมุมมองโปรเจ็กต์ในสตูดิโอ ตัวเลือกนี้จะรันเฉพาะงานตรวจแก้จุดบกพร่องเท่านั้น 2. นี่ดูเหมือนจะเป็นข้อจำกัดของ ndk-build ไม่ทราบว่าตัวเลือก NDK_DEBUG มีการเปลี่ยนแปลง - person DeathlessHorsie; 28.07.2015
comment
@DeathlessHorsie ตามที่ฉันเข้าใจ คุณได้ใช้วิธีแก้ปัญหาข้างต้นสำหรับ CompilDebugNdk และ CompileReleaseNdk แยกต่างหากโดยที่ค่าสถานะ Debug หายไปในส่วนหลัง แต่ปัญหาคือมันไม่คอมไพล์ใหม่เมื่อสลับระหว่าง Debug และ Release ใช่ไหม? คุณสามารถทำให้ส่วน NDK สะอาดก่อนคอมไพล์ได้เสมอ ซึ่งไม่เหมาะ แต่นี่เป็นปัญหาเดียวกันหากคุณลองสิ่งที่คล้ายกันที่บรรทัดคำสั่งด้วย make BTW ฉันคอมไพล์โดยใช้ ./gradlew assembleDebug หรือ assembleRelease - person Cameron Lowell Palmer; 28.07.2015
comment
@CameronLowellPalmer ขอบคุณฉันอัปเดตบิลด์และดูเหมือนว่าจะทำงานได้อย่างถูกต้อง - person Zoccadoum; 30.07.2015
comment
ฉันจะกำหนด sourceSets.main ได้อย่างไรเมื่อฉันใช้ปลั๊กอินทดลอง - person Shailen; 30.10.2015
comment
คุณสมควรได้รับคุกกี้! - person dbm; 20.12.2015
comment
ความคิดเห็น This is not necessary unless you have precompiled libraries in your project. ทำให้เข้าใจผิด ฉันต้องเพิ่มมัน ไม่เช่นนั้น อ็อบเจ็กต์ที่แชร์ที่สร้างขึ้นจะไม่เข้าไปในไฟล์ APK สุดท้าย - person Torsten Robitzki; 29.01.2016
comment
คุณสามารถค้นหาไดเรกทอรี NDK ได้ผ่านทางตัวแปรสภาพแวดล้อม NDK_ROOT_DIRCTORY. หาก Android Studio ละเว้นค่า คุณควรยื่นรายงานข้อบกพร่อง - person jww; 15.10.2016
comment
@jww คุณควรอัปเกรดเป็น 2.2.1 และลืม NDK_ROOT_DIRECTORY ไปได้เลย - person Cameron Lowell Palmer; 15.10.2016
comment
@CameronLowellPalmer - เท่าที่ฉันรู้ ทีม NDK ยังคงแนะนำ หาก Android Studio เพิกเฉย ให้ยื่นรายงานข้อบกพร่อง ดูเหมือนว่า Android Studio จะสร้างเรื่องไร้สาระขึ้นมาทันที - person jww; 15.10.2016
comment
@jww จริง ๆ แล้วฉันทำการรวบรวมส่วนใหญ่ผ่านการไล่ระดับตรงที่บรรทัดคำสั่ง ปลั๊กอิน android gradle 2.2.1 จะล้างปัญหาที่เกี่ยวข้องกับ NDK ส่วนใหญ่ซึ่งบังคับให้คุณโทร ndk-build ด้วยตนเองและเพิ่มการสนับสนุน cmake - person Cameron Lowell Palmer; 15.10.2016
comment
แทนที่จะซ่อนแหล่งที่มาของ C++ ฉันชอบที่จะปิดการใช้งาน complieXxxNdk โดยการเพิ่มเสน่ห์ต่อไปนี้ใน build.gradle: tasks.all { task -> if (task.name.contains('compileDebugNdk') || task.name.contains('compileReleaseNdk')) { task.enabled = false } } - person Alex Cohn; 07.12.2016
comment
@AlexCohn ขาดบริบทของความคิดเห็นนั้น - person Cameron Lowell Palmer; 07.12.2016
comment
ฉันปิดการใช้งานเหล่านี้แทนที่จะเขียน sourceSets.main { jni.srcDirs = [] } ดู stackoverflow.com/a/32640823/192373 - person Alex Cohn; 07.12.2016
comment
@AlexCohn อ่าใช่ อย่างไรก็ตาม นั่นไม่จำเป็นอีกต่อไปหากคุณอัปเกรดเพื่อสร้างเครื่องมือเป็น 2.2.x+ - person Cameron Lowell Palmer; 07.12.2016
comment
ยังคงมีสถานการณ์ที่ externalNativeBuild ไม่สามารถใช้งานได้ - person Alex Cohn; 07.12.2016
comment
@AlexCohn ใช่ฉันแน่ใจ แค่คนส่วนใหญ่คงไม่ต้องการอะไรอีกแล้ว มันคือหนทางข้างหน้า! :) - person Cameron Lowell Palmer; 07.12.2016

gradle รองรับการคอมไพล์ ndk โดยสร้างไฟล์ Android.mk อื่นพร้อมเส้นทางที่แน่นอนไปยังแหล่งที่มาของคุณ NDK รองรับเส้นทางแบบสัมบูรณ์ตั้งแต่ r9 บน OSX, r9c บน Windows ดังนั้นคุณจึงต้องอัปเกรด NDK ของคุณเป็น r9+

คุณอาจประสบปัญหาอื่น ๆ เนื่องจากการสนับสนุน NDK โดยการไล่ระดับเป็นเบื้องต้น หากเป็นเช่นนั้นคุณสามารถปิดการใช้งานการคอมไพล์ ndk จาก gradle ได้โดยการตั้งค่า:

sourceSets.main {
    jni.srcDirs = []
    jniLibs.srcDir 'src/main/libs'
}

เพื่อให้สามารถเรียก ndk-build ด้วยตัวเองและรวม libs จาก libs/

ว่าแต่คุณมีปัญหาในการคอมไพล์สำหรับ x86 หรือไม่? ฉันเห็นว่าคุณไม่ได้รวมไว้ใน APP_ABI ของคุณ

person ph0b    schedule 14.01.2014
comment
คำตอบที่ดี! คุณทำให้วันของฉัน! =) วิธีแก้ไขปัญหาอื่น ฉันไม่พบ - person Vlad Hudnitsky; 03.02.2014
comment
ประสบปัญหาเดียวกันกับตัวเอง ฉันแก้ไขมันด้วยการเพิ่มไฟล์ .c เปล่าลงในไดเร็กทอรี ./app/src/main/jni (ฉันตั้งชื่อไฟล์ว่า utils.c แต่คุณสามารถเรียกมันว่าอะไรก็ได้ที่คุณต้องการ...) ตั้งแต่นั้นมาทุกอย่างก็ทำงานได้ดี ฉันไม่ได้เปลี่ยนแปลงอะไรในไฟล์การตั้งค่า Gradle - person GeertVc; 17.09.2014
comment
ฉันควรใส่สิ่งนี้ไว้ใต้ผู้ปกครองคนใด ฉันลองมาสองแห่งแล้ว แต่กลับไม่สามารถแก้ไขสัญลักษณ์: jni ได้ - person Andrew Wyld; 19.01.2015
comment
คุณควรวางไว้ใต้ android { } - person ph0b; 20.01.2015
comment
นั่นได้ผลสำหรับฉัน ใครช่วยอธิบายคำตอบโดยละเอียดหน่อยได้ไหม - person Amit Gupta; 06.07.2015
comment
คุณสามารถดูรายละเอียดเพิ่มเติมจากบทความของฉัน: ph0b.com/android-studio- gradle-และ-ndk-บูรณาการ - person ph0b; 06.07.2015

ในกรณีของฉัน ฉันใช้ Windows และทำตามคำตอบของ Cameron ด้านบนจะใช้งานได้ก็ต่อเมื่อคุณใช้ชื่อเต็มของ ndk-build ซึ่งก็คือ ndk-build.cmd ฉันต้องล้างและสร้างโปรเจ็กต์ใหม่ จากนั้นรีสตาร์ทโปรแกรมจำลองก่อนที่จะทำให้แอปทำงานได้ (จริงๆ แล้วฉันนำเข้าตัวอย่าง HelloJni จาก NDK ไปยัง Android Studio) อย่างไรก็ตาม ตรวจสอบให้แน่ใจว่า เส้นทางไปยัง NDK ไม่มีช่องว่าง

ในที่สุด build.gradle ของฉันก็มีรายการเต็มดังนี้:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.hellojni"
        minSdkVersion 4
        targetSdkVersion 4

        ndk {
            moduleName "hello-jni"
        }

        testApplicationId "com.example.hellojni.tests"
        testInstrumentationRunner "android.test.InstrumentationTestRunner"
    }
    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
//        sourceSets.main.jni.srcDirs = []
        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.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-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.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-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:21.0.3'
}
person Brian Ng    schedule 09.03.2015
comment
นามสกุลไฟล์! คงจะรักวินโดวส์ - person Cameron Lowell Palmer; 21.12.2015
comment
อะไรอยู่ข้างใน src/main/libs? จะเป็นอย่างไรหากเป็นไดเรกทอรีย่อยอื่นเช่น armeabi - person IgorGanapolsky; 11.05.2016
comment
รายการไฟล์ .so ที่ฉันอาจเพิ่ม ในโปรเจ็กต์ที่ผ่านมาของฉันคือ opencv libs สำหรับ Android - person Brian Ng; 14.05.2016
comment
คุณสามารถค้นหาไดเรกทอรี NDK ได้ผ่านทางตัวแปรสภาพแวดล้อม NDK_ROOT_DIRCTORY. หาก Android Studio ละเว้นค่า คุณควรยื่นรายงานข้อบกพร่อง - person jww; 15.10.2016

Android Studio 2.2 ออกมาพร้อมกับความสามารถในการใช้ ndk-build และ cMake แม้ว่าเราจะต้องรอจนถึง 2.2.3 สำหรับการรองรับ Application.mk ฉันได้ลองแล้ว มันใช้งานได้...แต่ตัวแปรของฉันไม่แสดงในดีบักเกอร์ ฉันยังคงสามารถสอบถามพวกเขาผ่านทางบรรทัดคำสั่งได้

คุณต้องทำสิ่งนี้:

externalNativeBuild{
   ndkBuild{
        path "Android.mk"
    }
}

defaultConfig {
  externalNativeBuild{
    ndkBuild {
      arguments "NDK_APPLICATION_MK:=Application.mk"
      cFlags "-DTEST_C_FLAG1"  "-DTEST_C_FLAG2"
      cppFlags "-DTEST_CPP_FLAG2"  "-DTEST_CPP_FLAG2"
      abiFilters "armeabi-v7a", "armeabi"
    }
  } 
}

ดู http://tools.android.com/tech-docs/external-c-builds

หมายเหตุ: การซ้อนเพิ่มเติมของ externalNativeBuild ภายใน defaultConfig เป็นการเปลี่ยนแปลงครั้งใหญ่ที่เกิดขึ้นใน Android Studio 2.2 ตัวอย่าง 5 (8 กรกฎาคม 2016) ดูบันทึกประจำรุ่นได้ที่ลิงค์ด้านบน

person Ronnie    schedule 16.06.2016
comment
คุณช่วยอธิบายอย่างละเอียดได้ไหม แต่เราต้องรอจนถึง 2.2.3 สำหรับการรองรับ Application.mk นั่นคือ Preview3 หรือ.. ? - person Sebastian Roth; 30.06.2016
comment
@SebastianRoth: ใช่มันเป็นการแสดงตัวอย่าง 3 ณ วันนี้ 8 สิงหาคม 2558 Android Studio 2.2 Beta ได้รับการเผยแพร่ซึ่งให้การสนับสนุนการสร้างเนทิฟภายนอก - person Vyshakh Amarnath; 10.08.2016

ปัญหาของฉันใน OSX เป็นเวอร์ชัน gradle Gradle ไม่สนใจ Android.mk ของฉัน ดังนั้น เพื่อแทนที่ตัวเลือกนี้ และใช้ make ของฉันแทน ฉันได้ป้อนบรรทัดนี้:

sourceSets.main.jni.srcDirs = []

ภายในแท็ก android ใน build.gradle

ฉันเสียเวลาไปมากกับเรื่องนี้!

person Paschalis    schedule 26.02.2014
comment
ฉันไม่เข้าใจ เพราะ @CameronLowellPalmer ได้ระบุสิ่งนี้ไว้ หรือ gradle ตีความ sourceSets.main { jni.srcDirs = [] } แตกต่างจาก sourceSets.main.jni.srcDirs = [] ในทางใดทางหนึ่ง? ฉันเชื่อว่าปัญหาของคุณอยู่ที่อื่นและคุณแก้ไขโดยไม่ได้ตั้งใจ - person Oliver Hausler; 11.01.2015
comment
@OliverHausler ทั้งสองคำสั่งนั้นเทียบเท่ากัน - person Cameron Lowell Palmer; 26.01.2015

ในโมดูล build.gradle ในช่องงาน ฉันได้รับข้อผิดพลาดเว้นแต่ฉันจะใช้:

def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()

เห็นคนใช้.

def ndkDir = android.plugin.ndkFolder

และ

def ndkDir = plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()

แต่ทั้งสองอย่างไม่ได้ผลจนกว่าฉันจะเปลี่ยนเป็นปลั๊กอินที่ฉันนำเข้าจริง

person videogameboy76    schedule 26.06.2015
comment
คุณสามารถค้นหาไดเรกทอรี NDK ได้ผ่านทางตัวแปรสภาพแวดล้อม NDK_ROOT_DIRCTORY. หาก Android Studio ละเว้นค่า คุณควรยื่นรายงานข้อบกพร่อง - person jww; 15.10.2016