एंड्रॉइड स्टूडियो, ग्रेडल और एनडीके


153

मैं इस पूरे ग्रेडेल और एंड्रॉइड स्टूडियो समर्थन के लिए बहुत नया हूं। मैं निर्यात विकल्प का उपयोग करके अपने एंड्रॉइड प्रोजेक्ट को बदलने में कामयाब रहा हूं।

लेकिन मैं कुछ प्रलेखन की तलाश कर रहा हूं या एनडीके बिल्ड को ग्रेडल निर्माण प्रक्रिया में एकीकृत करने के बिंदु शुरू कर रहा हूं।

यदि संभव हो तो मुझे किसी प्रकार के "बाद" चरण की भी आवश्यकता है जो बिल्ड बायनेरिज़ (.so फ़ाइलों) को संपत्ति निर्देशिका में कॉपी करता है।


मैंने नीचे दिए गए लिंक stackoverflow.com/questions/20900814/…
अहमद अली नासिर

24
नए पाठक: इस सवाल से अवगत रहें कि शुरुआत में एंड्रॉइड स्टूडियो बीटा अवधि के दौरान पूछा गया था; समय के साथ उत्तर बदल गया है। उत्तर में उल्लिखित ग्रेड संस्करण पर ध्यान दें, साथ ही जब उत्तर वास्तव में पोस्ट किए गए थे।
सीन बीच

यदि वास्तव में कुछ बदलता है तो मैं स्थिति को फिर से देखने के लिए प्रश्न को संपादित करूंगा
plaisthos

कैनरी चैनल पर एंड्रॉइड स्टूडियो 1.3 पूरी तरह से एनडीके का समर्थन करता है। संदर्भ: tools.android.com/download/studio/canary/latest
विकासदीप सिंह

जून 18, 2015: एंड्रॉइड स्टूडियो 1.3 बीटा अब बीटा चैनल में उपलब्ध है! क्षमा करें, इस बिल्ड में अभी तक C / C ++ समर्थन नहीं है; स्रोत: tools.android.com/recent/androidstudio13betaavailable
fastr.de

जवाबों:


85

हमने 1.3 में पूर्वावलोकन के रूप में एकीकरण का पहला संस्करण जारी किया है: http://tools.android.com/tech-docs/android-ndk-preview

1.3 अंतिम बनने के बाद भी एकीकरण एक पूर्वावलोकन रहेगा। कोई वर्तमान ईटीए के रूप में जब यह अंतिम होगा (2015/07/10 के अनुसार)।

अधिक जानकारी यहाँ: http://tools.android.com/tech-docs/android-ndk-preview


2
बहुत अच्छा होगा अगर मैं एंड्रॉइड स्टूडियो (और
ग्रैडल

1
@GREnvoy - हम एंड्रॉइड स्टूडियो में सही NDK बिल्डर को कैसे कॉन्फ़िगर करते हैं? क्या आप मुझे चरण दे सकते हैं? :)
श्रावण

7
@DirtyBeach यह पुराना क्यों है? स्टूडियो में अभी भी NDK का एकीकरण नहीं है। हम इस पर काम कर रहे हैं लेकिन इस समय कोई ई.टी.ए.
जेवियर डुक्रोएट

2
मेरी कार्रवाई इस बात पर आधारित थी कि मैं "एकीकरण" को कैसे परिभाषित कर रहा हूं। मैंने इसे "एनडीके को ग्रेडेल के साथ उपयोग करने का एक तरीका" समझा, जो अब मौजूद है, उनमें से कोई भी शानदार समाधान नहीं है। हालाँकि, आपकी टिप्पणी के आधार पर, ऐसा लगता है कि आपकी टीम के दिमाग में कुछ और है जो एक सच्चा एकीकरण हो सकता है। मैं अपने पिछले बयान को वापस लेता हूं।
सीन बीच

2
Google IO 2015 के दौरान NDK एकीकरण की घोषणा की गई थी। यह एंड्रॉइड स्टूडियो 1.3 में उपलब्ध है (पूर्वावलोकन जल्द ही डाउनलोड किया जा सकता है। जब यह उपलब्ध होगा तो मैं एक लिंक पोस्ट करूंगा)।
सरू फ्रैंकनफेल्ड

43

अद्यतन: NDK समर्थन वाला Android स्टूडियो अब बाहर है: http://tools.android.com/tech-docs/android-ndk-preview

एक स्क्रिप्ट के साथ निर्माण के लिए नीचे दिए गए हल का हल काम करना चाहिए:

मैं अपनी बिल्ड स्क्रिप्ट का उपयोग कर रहा हूं और मेरी फ़ाइल में जोड़ा गया है (इसके लिए काम करने लगता है 0.8+): यह नीचे दिए गए समाधान के बराबर लगता है (लेकिन ग्रेड फ़ाइल में अच्छे लगते हैं):

 android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['native-libs']
            jni.srcDirs = [] //disable automatic ndk-build
        }
    }
 }

यदि निर्देशिका मौजूद नहीं है या कोई .soफ़ाइल नहीं है, तो दुर्भाग्य से बिल्ड विफल नहीं होता है।


5
यह अब नए एंड्रॉइड स्टूडियो संस्करण के साथ काम नहीं करता है, वर्कअराउंड?
पाउडर 366

@ powder366 मेरा जवाब देखें।
लिएंड्रो डिस

2
थोड़ा ग्रूवी जादू tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }:। मदद के लिए धन्यवाद दोस्तों!
trnl

एंड्रॉइड स्टूडियो 0.8.9 के लिए प्रक्रिया क्या है
पंडिरी दीपक

1
@plaisthos सही दिशा बताने के लिए बहुत बहुत धन्यवाद! ग्रेड स्क्रिप्ट में दूसरी पंक्ति jni.srcDirs = [] //disable automatic ndk-buildबहुत महत्वपूर्ण है क्योंकि यह एंड्रॉइड स्टूडियो को C / C ++ स्रोत कोड के पुनर्निर्माण से रोक देगा। मैं दो दिनों के लिए यह पता लगाने की कोशिश कर रहा हूं जब तक मैंने आपकी पोस्ट नहीं देखी और इससे मेरी समस्या हल हो गई। मुझे वास्तव में लगता है कि NDK बिल्ड बेहतर है। इसे अलग से Android.mk कमांड लाइन मेकफाइल द्वारा ही बनाया गया है, न कि ग्रेडल स्क्रिप्ट द्वारा, क्योंकि C / C ++ को मेकफाइल द्वारा 40 से अधिक वर्षों के लिए बनाया गया है!
टोंगा

40

एंड्रॉइड स्टूडियो के 1.0 के अपडेट के साथ, एनडीके टूलचैन समर्थन में काफी सुधार हुआ ( ध्यान दें: कृपया इस पोस्ट के निचले भाग पर मेरे अपडेट को नए प्रयोगात्मक ग्रेडल प्लगइन और एंड्रॉइड स्टूडियो 1.5 के साथ उपयोग करने के लिए पढ़ें )।

एंड्रॉइड स्टूडियो और एनडीके को अच्छी तरह से एकीकृत किया जाता है ताकि आपको अपने मॉड्यूल के build.gradle में एक ndk {} ब्लॉक बनाने की आवश्यकता हो, और अपने स्रोत फ़ाइलों को (मॉड्यूल) / src / main / jni निर्देशिका में सेट करें - और आप किया हुआ!

कमांड लाइन से अधिक ndk-build नहीं।

मैंने अपने ब्लॉग पोस्ट में इसके बारे में सब कुछ यहाँ लिखा है: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

मुख्य बिंदु हैं:

यहां आपको दो चीजें जानने की जरूरत है। डिफ़ॉल्ट रूप से, यदि आपके बाहरी लोड हैं, जिन्हें आप Android एप्लिकेशन में लोड करना चाहते हैं, तो उन्हें डिफ़ॉल्ट रूप से (मॉड्यूल) / src / main / jniLibs के लिए देखा जाता है। आप अपने मॉड्यूल के build.gradle में sourceSets.main.jniLibs.srcDirs की सेटिंग का उपयोग करके इसे बदल सकते हैं। आपको प्रत्येक आर्किटेक्चर के लिए पुस्तकालयों के साथ एक उपनिर्देशिका की आवश्यकता होगी जिसे आप लक्षित कर रहे हैं (जैसे x86, हाथ, mips, arm64-v8a, आदि)

जिस कोड को आप डिफ़ॉल्ट रूप से NDK टूलकिन द्वारा संकलित करना चाहते हैं, वह (मॉड्यूल) / src / main / jni में स्थित होगा और इसी तरह ऊपर, आप अपने मॉड्यूल के build.gradle में sourceSets.main.jni.srcDirs सेट करके इसे बदल सकते हैं।

और इसे अपने मॉड्यूल के build.gradle में डालें:

ndk {
  moduleName "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
  cFlags "-std=c++11 -fexceptions" // Add provisions to allow C++11 functionality
  stl "gnustl_shared" // Which STL library to use: gnustl or stlport
}

यह आपके C ++ कोड को संकलित करने की प्रक्रिया है, वहां से आपको इसे लोड करने की आवश्यकता है, और रैपर बनाने की आवश्यकता है - लेकिन अपने प्रश्न से देखते हुए, आप पहले से ही जानते हैं कि यह सब कैसे करना है, इसलिए मैं फिर से हैश नहीं करूंगा।

इसके अलावा, मैंने इस उदाहरण का एक Github रेपो यहां रखा है: http://github.com/sureshjoshi/android-ndk-swig-example

अद्यतन: 14 जून, 2015

जब एंड्रॉइड स्टूडियो 1.3 बाहर आता है, तो JetBrains CLion प्लगइन के माध्यम से C ++ के लिए बेहतर समर्थन होना चाहिए। मैं वर्तमान में इस धारणा के तहत हूं कि यह एंड्रॉइड स्टूडियो के भीतर जावा और सी ++ विकास की अनुमति देगा; हालाँकि मुझे लगता है कि हमें अभी भी ग्रेडल एनडीके अनुभाग का उपयोग करने की आवश्यकता होगी जैसा कि मैंने ऊपर कहा है। इसके अतिरिक्त, मुझे लगता है कि अभी भी जावा <-> C ++ रैपर फ़ाइलों को लिखने की आवश्यकता होगी, जब तक कि CLion स्वचालित रूप से ऐसा नहीं करेगा।

अद्यतन: 5 जनवरी, 2016

मैंने अपने ब्लॉग और जीथब रेपो (विकसित शाखा में) को नवीनतम प्रयोगात्मक ग्रैडल प्लगइन (0.6.0-अल्फा 3) के साथ एंड्रॉइड स्टूडियो 1.5 का उपयोग करने के लिए अपडेट किया है।

http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ http://github.com/sureshjoshi/android-ndk-swig-example

NDK सेक्शन के लिए ग्रैड बिल्ड अब इस तरह दिखता है:

android.ndk {
    moduleName = "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
    cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
    cppFlags.add("-fexceptions")
    stl = "gnustl_shared" // Which STL library to use: gnustl or stlport
}

इसके अलावा, काफी अजीब तरह से, एंड्रॉइड स्टूडियो में C ++ के लिए ऑटो-पूर्ण है - 'मूल' कीवर्ड का उपयोग करके जावा उत्पन्न रैपर:

C ++ - Java आवरण के स्वतः पूर्ण होने का उदाहरण

हालाँकि, यह पूरी तरह से रस्साकसी नहीं है ... यदि आप ऑटो-कोड कोड के लिए लाइब्रेरी को लपेटने के लिए SWIG का उपयोग कर रहे हैं, और फिर मूल कीवर्ड ऑटो-पीढ़ी का उपयोग करने का प्रयास करते हैं, तो यह कोड को आपके Swig _wrap में गलत स्थान पर डाल देगा। .cxx फ़ाइल ... तो आपको इसे "एक्सटर्नल सी" ब्लॉक में ले जाना होगा:

C ++ - Java रैपर सही स्थान पर चला गया

अद्यतन: 15 अक्टूबर, 2017

यदि मैं यह उल्लेख नहीं करता कि मैं एंड्रॉइड स्टूडियो 2.2 के बाद मूल रूप से 'देशी' (कोई दंड नहीं) का समर्थन करता हूं, तो ग्रेड और सीमेक के माध्यम से एनडीके टूलचैन के लिए मुझे याद होगा। अब, जब आप एक नया प्रोजेक्ट बनाते हैं, तो बस C ++ सपोर्ट चुनें और आप जाने के लिए अच्छे हैं।

आपको अभी भी अपना स्वयं का जेएनआई लेयर कोड जनरेट करना होगा, या मैंने ऊपर बताई गई SWIG तकनीक का उपयोग किया होगा, लेकिन Android प्रोजेक्ट में C ++ का मचान अब तुच्छ है।

CMakeLists फ़ाइल में परिवर्तन (जो आप अपनी C ++ स्रोत फ़ाइलों को रखते हैं) को एंड्रॉइड स्टूडियो द्वारा उठाया जाएगा, और यह स्वचालित रूप से किसी भी संबंधित लाइब्रेरी को फिर से संकलित करेगा।


1
* .so में (मॉड्यूल) / src / मुख्य / jniLibs डाल
फॉक्स

NDEBUG एंड्रॉइड स्टूडियो का उपयोग करते समय हमेशा सेट क्यों होता है, यहां तक ​​कि डिबग बिल्ड पर भी
pt123

35

Google IO 2015 में, Google ने Android Studio 1.3 में पूर्ण NDK एकीकरण की घोषणा की।

यह अब पूर्वावलोकन से बाहर है, और सभी के लिए उपलब्ध है: https://developer.android.com/studio/projects/add-native-code.html

पुराना उत्तर: ndk-buildयदि jniआपके प्रोजेक्ट स्रोतों में कोई निर्देशिका है तो ग्रैडल स्वचालित रूप से कॉल करता है।

यह एंड्रॉइड स्टूडियो 0.5.9 (कैनरी बिल्ड) पर काम कर रहा है।

  1. NDK डाउनलोड करें

  2. या तो ANDROID_NDK_HOMEअपने पर्यावरण चर में जोड़ें या अपने एंड्रॉइड स्टूडियो प्रोजेक्ट में अपने ndk.dir=/path/to/ndkको जोड़ें local.properties। यह एंड्रॉइड स्टूडियो को स्वचालित रूप से एनडीके चलाने की अनुमति देता है।

  3. Ndk प्रोजेक्ट का उदाहरण देखने के लिए नवीनतम ग्रेडल नमूना प्रोजेक्ट डाउनलोड करें । (वे पृष्ठ के निचले भाग पर हैं)। एक अच्छा नमूना प्रोजेक्ट है ndkJniLib

  4. gradle.buildNDK नमूना परियोजनाओं से कॉपी करें । यह कुछ इस तरह दिखेगा। यह gradle.buildप्रत्येक आर्किटेक्चर के लिए एक अलग apk बनाता है। आपको चयन करना होगा कि आप किस वास्तुकला का उपयोग करना चाहते हैं build variantsवेरिएंट फलक बनाएँ

    apply plugin: 'android'
    
    dependencies {
        compile project(':lib')
    }
    
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.2"
    
        // This actual the app version code. Giving ourselves 100,000 values [0, 99999]
        defaultConfig.versionCode = 123
    
        flavorDimensions "api", "abi"
    
        productFlavors {
            gingerbread {
                flavorDimension "api"
                minSdkVersion 10
                versionCode = 1
            }
            icecreamSandwich {
                flavorDimension "api"
                minSdkVersion 14
                versionCode = 2
            }
            x86 {
                flavorDimension "abi"
                ndk {
                    abiFilter "x86"
                }
                // this is the flavor part of the version code.
                // It must be higher than the arm one for devices supporting
                // both, as x86 is preferred.
                versionCode = 3
            }
            arm {
                flavorDimension "abi"
                ndk {
                    abiFilter "armeabi-v7a"
                }
                versionCode = 2
            }
            mips {
                flavorDimension "abi"
                ndk {
                    abiFilter "mips"
                }
                versionCode = 1
            }
            fat {
                flavorDimension "abi"
                // fat binary, lowest version code to be
                // the last option
                versionCode = 0
            }
        }
    
        // make per-variant version code
        applicationVariants.all { variant ->
            // get the version code of each flavor
            def apiVersion = variant.productFlavors.get(0).versionCode
            def abiVersion = variant.productFlavors.get(1).versionCode
    
            // set the composite code
            variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode
        }
    
    }

ध्यान दें कि यह आपके Android.mk और Application.mk फ़ाइलों को अनदेखा करेगा। वर्कअराउंड के रूप में, आप एटमॉमेटिक एनडीके-बिल्ड कॉल को अक्षम करने के लिए ढाल बता सकते हैं, फिर एनडीआर स्रोतों के लिए निर्देशिका को मैन्युअल रूप से निर्दिष्ट करें।

sourceSets.main {
    jniLibs.srcDir 'src/main/libs' // use the jni .so compiled from the manual ndk-build command
    jni.srcDirs = [] //disable automatic ndk-build call
}

इसके अलावा, आप संभवतः अपने ग्रेडेल स्क्रिप्ट में ndk-build को स्पष्ट रूप से कॉल करना चाहेंगे, क्योंकि आपने अभी-अभी स्वचालित कॉल को अक्षम किया है।

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

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

हाँ। लेकिन यह केवल यूनिक्स प्लेटफार्मों के तहत काम करता है और सीमित भी अगर आप बहुत सरल एनडीके कॉन्फ़िगरेशन / मेकफाइल्स की तुलना में अधिक जटिल हैं।
प्लासथोस

हां, यह उन सीमित चीजों के लिए मेकओफाइल्स को स्वचालित कर देगा जिन्हें आप ग्रेडल बिल्ड फ़ाइल में सेट कर सकते हैं, हालांकि वर्कअराउंड है। मैंने इसे अपने जवाब में जोड़ दिया।
सरू फ्रैंकनफेल्ड

1
Ndk-build का कॉल केवल एंड्रॉइड स्टूडियो के भीतर से नहीं, कमांड-लाइन पर काम करेगा।
कैमरन लोवेल पामर

हालांकि यह सबसे हालिया उत्तर नहीं है, लेकिन यह सबसे सटीक होने की संभावना है। चरण 3 पर विशेष ध्यान दें: " नवीनतम ग्रेडेल नमूना परियोजनाएं डाउनलोड करें "।
सीन बीच

4
मैं src dir को tasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
डिसेबल

23

मैंने पाया "gradle 1.11 com.android.tools.build:gradle if.9.+" अब प्री-बिल्ड ndk को सपोर्ट करता है, आप सिर्फ dir src / main / jniLibs में * .so डाल सकते हैं। जब ढाल का निर्माण ndk को सही जगह पर पैकेज करेगा।

यहाँ मेरा प्रोजेक्ट है

परियोजना:
| --src
| - | --main
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | - | - तो फ़ाइलें
| --libs
| - | --other.jar

18

जैसा कि जेवियर ने कहा, आप अपने प्रीपेट्स को / src / main / jniLibs में डाल सकते हैं / यदि आप ग्रेडिंग 0.7.2+ का उपयोग कर रहे हैं

इससे लिया गया: https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/ctDp9viWaxoJ


हम 0.7.2 ndkJniLib में मानसिक रूप से नमूने को कैसे देख सकते हैं?
रेयान हेटनर

SqlCipher
personne3000

16

अब तक (Android Studio v0.8.6) यह काफी सरल है। यहां "हैलो वर्ल्ड" टाइप ऐप बनाने के चरण दिए गए हैं:

  1. एंड्रॉइड एनडीके डाउनलोड करें और रूट फ़ोल्डर को कहीं भी रखें - एसडीके फ़ोल्डर के समान स्थान में, शायद।

  2. अपनी local.propertiesफ़ाइल में निम्न जोड़ें : ndk.dir=<path-to-ndk>

  3. लाइन के defaultConfigठीक बाद अपनी बिल्ड.gradle फ़ाइल को क्लोजर के अंदर निम्न जोड़ें versionName:ndk { moduleName="hello-world" }

  4. अपने ऐप मॉड्यूल की mainनिर्देशिका में, एक नया फ़ोल्डर बनाएं जिसे कहा जाता है jni

  5. उस फ़ोल्डर में, एक फाइल बनाएं hello-world.c, जिसे आप नीचे देखेंगे।

  6. Activityकिसी विधि को कॉल करने के तरीके (या यह एक फ़ंक्शन है?) के उदाहरण के लिए नीचे दिया गया उदाहरण कोड देखें hello-world.c


hello-world.c

#include <string.h>
#include <jni.h>

jstring
Java_me_mattlogan_ndktest_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
    return (*env)->NewStringUTF(env, "Hello world!");
}

MainActivity.java

public class MainActivity extends Activity {

    static {
        System.loadLibrary("hello-world");
    }

    public native String stringFromJNI();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String testString = stringFromJNI();

        TextView mainText = (TextView) findViewById(R.id.main_text);
        mainText.setText(testString);
    }
}

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "me.mattlogan.ndktest"
        minSdkVersion 15
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "hello-world"
        }
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

यहां एक समान एप्लिकेशन का पूर्ण स्रोत कोड खोजें (माइनस द एनडीके)।


मैं अपने वर्तमान प्रोजेक्ट में बिल्कुल निर्देश के अनुसार काम कर रहा हूं, लेकिन NDK सामान अभी भी नहीं बन रहा है। कोई विचार? ऐसा लगता है कि यह सब कुछ बना रहा है, लेकिन सिर्फ जेन सामान छोड़ रहा है।
alice.harrison

@NannuoLei धन्यवाद, मैंने कोशिश की लेकिन मुझे एक समस्या मिल रही है जहाँ .so उत्पन्न नहीं हो रहा है। बाकी सब काम करने लगता है, लेकिन जब मैं एमुलेटर में एपीकेजी चलाता हूं, तो यह शिकायत करता है कि यह साझा किए गए ऑब्जेक्ट को लोड नहीं कर सकता है।
९ ०२०५

@ aa90210 एक x86 छवि पर आधारित आपका एमुलेटर है? डिफ़ॉल्ट रूप से NDK सिर्फ एक ARMEABI लाइब्रेरी का निर्माण करेगा, यदि आप एक x86 इमेज बनाना चाहते हैं तो आप इस लाइन को Application.mk में जोड़ सकते हैं: APP_ABI: = armeabi x86
लियो मोनिका सेलियो

1
इसने मेरे साथ काम किया। पुनश्च: किसी को भी इस जवाब को देखकर, Java_me_mattlogan_ndktest_MainActivity_stringFromJNIअपने आप को बदलने के लिए मत भूलना :)
अब्दुलमेन عبدالمؤمن

8

यदि आप यूनिक्स पर हैं तो नवीनतम संस्करण (0.8) एनडीके-बिल्ड जोड़ता है। इसे जोड़ने का तरीका यहां दिया गया है:

android.ndk {
    moduleName "libraw"
}

यह 'src / main / jni' के तहत JNI को खोजने की अपेक्षा करता है, अन्यथा आप इसे इसके साथ परिभाषित कर सकते हैं:

sourceSets.main {
    jni.srcDirs = 'path'
}

संस्करण 0.8 के साथ 28 JAN 2014 के रूप में निर्माण खिड़कियों पर टूट गया है, आपको बिल्ड को इसके साथ अक्षम करना होगा:

sourceSets.main {
    jni.srcDirs = [] //disable automatic ndk-build call (currently broken for windows)
}

1
क्या उस सुविधा का कोई दस्तावेज है? मुझे कोई नहीं मिला। इस समय जो पूरी तरह से मेरे Android.mk/Application.mk को नजरअंदाज कर रहा है।
प्लैसथोस २14

मुझे कोई नहीं मिला है। यह बिल्ड-बेक्ड में सूँघ सकता है। मैं खिड़कियों पर हूं इसलिए मैं केवल यह पुष्टि कर सकता हूं कि यह यूनिक्स एनडीके-बिल्ड स्क्रिप्ट को कॉल करने की कोशिश में विफल है। उसके बाद कॉल करने के लिए कोई अन्य कारण नहीं होगा, ताकि मूल संकलन को ग्रेडेल में एकीकृत किया जा सके। क्या आप यूनिक्स में हैं?
एंथनी


यह वास्तव में प्रीबिलीट * .so फ़ाइलों को jniLibs.srcDirs में खोजने की उम्मीद करता है
अल्पाइन

मैं इस तथ्य पर आधारित असहमत हूं कि यह एनडीके-बिल्ड को क्रैश करता है जो बिल्ट लाइब्रेरी की आवश्यकता होने पर बिल्कुल आवश्यक नहीं है। मैं पुष्टि नहीं कर सकता क्योंकि अभी मेरे पास लिनक्स को वीएम करने का समय नहीं है।
एंथनी

7

Https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J में एक सुरुचिपूर्ण समाधान दिखाया गया है ।

मूल रूप से आप एक जार बनाते हैं जिसमें "lib / armeabi / yourlib.so" होता है और फिर निर्माण में जार शामिल करें।


हाँ। यदि आप अपने कोड को अक्सर देशी नहीं बदलते हैं तो यह अच्छी तरह से काम करता है। और आपको रिपॉजिटरी में बाइनरी जार फ़ाइलों को शामिल करना होगा। अन्यथा आप एक बिल्ड स्क्रिप्ट के साथ समाप्त होते हैं जो मक्खी पर एक जार बनाता है।
प्लैसथोस

1
मैंने एंड्रॉइड के हैलो-जेएनआई उदाहरण को एक साधारण बैश स्क्रिप्ट के साथ संशोधित किया है जो लपेटता है ndk-build, .jarप्रत्येक के लिए एस उत्पन्न करता है .soऔर उन्हें इस दर्द को कम करने के लिए ढाल के निर्माण पथ में रखता है। इसकी जांच - पड़ताल करें।
dbro

4

आसानी से संकलित .so-फाइल की पैकेजिंग को स्वचालित करने वाला एक अच्छा उत्तर दूसरे (बंद) धागे में दिया गया है । उस काम को करने के लिए मुझे लाइन बदलनी पड़ी:

from fileTree(dir: 'libs', include: '**/*.so')

में:

from fileTree(dir: 'src/main/libs', include: '**/*.so') 

इस परिवर्तन के बिना .soफाइलें नहीं मिलीं, और इसलिए उन्हें पैकेजिंग के लिए कार्य कभी नहीं चलेगा।


अपडेट: कृपया ध्यान दें कि नए एंड्रॉइड स्टूडियो में (कम से कम 1.5 में) देशी कोड को बेहतर तरीके से शामिल किया गया है, और अपने कोड की पैकेजिंग के लिए यह अलग कार्य करना आवश्यक नहीं है।
HYS

4

@Plaisthos से उत्तर नवीनतम ग्रेडल संस्करण में टूट गया, लेकिन अभी भी इसे करने का एक तरीका है। बनाओnative-libsअपनी परियोजना निर्देशिका की जड़ में निर्देशिका और इस निर्देशिका में हमारे सभी कामों की प्रतिलिपि बनाएँ।

निम्नलिखित बिल्ड को अपने build.gradle में जोड़ें। बनाएँ और खुश रहें।

task copyNativeLibs(type: Copy) {
    from(new File(project(':<your project>').getProjectDir(), 'native-libs')) { include '**/*.so' }
    into new File(buildDir, 'native-libs')
}

tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }

clean.dependsOn 'cleanCopyNativeLibs'

3

यह वह कोड है जिसका उपयोग मैं android-ndk को gradle से बनाने के लिए करता हूं। इसके लिए ndk डायरेक्टरी पाथ को gradle.propertiesयानि जोड़ें । ndkdir=/home/user/android-ndk-r9dएक फ़ोल्डर nativeमें सभी jni फाइल्स जोड़ें और डालें src/main/जैसा कि आप नीचे पोस्ट किए गए कोड से देख सकते हैं। यह देशी कामों के साथ जार बनाएगा जिसे आप सामान्य रूप से उपयोग कर सकते हैंSystem.loadLibrary("libraryname");

dependencies {
    compile fileTree(dir: "$buildDir/native-libs", include: '*.jar')
}

task ndkBuild(type: Exec) {
    commandLine "$ndkdir/ndk-build", "--directory", "$projectDir/src/main/native", '-j', Runtime.runtime.availableProcessors(),
            "APP_PLATFORM=android-8",
            "APP_BUILD_SCRIPT=$projectDir/src/main/native/Android.mk",
            "NDK_OUT=$buildDir/native/obj",
            "NDK_APP_DST_DIR=$buildDir/native/libs/\$(TARGET_ARCH_ABI)"
}

task nativeLibsToJar(type: Jar, description: 'create a jar with native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: "$buildDir/native/libs", include: '**/*.so')
    into 'lib/'
}

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

nativeLibsToJar.dependsOn 'ndkBuild'

3

मैंने देशी ड्रॉपबॉक्स पुस्तकालयों को संकलित करने के लिए निम्नलिखित कोड का उपयोग किया है, मैं एंड्रॉइड स्टूडियो v1.1 का उपयोग कर रहा हूं।

task nativeLibsToJar(type: Zip) {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'src/main/libs', include: '**/*.so')
    into 'lib/'
}

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

2

मैंने android स्टूडियो प्रोजेक्ट में local.properties फ़ाइल में ndk केndk.dir=/usr/shareData/android-ndk-r11b // पथ का उपयोग किया है । और इस लाइन को जोड़ें: android स्टूडियो प्रोजेक्ट में gradle.properties फ़ाइल में। अधिक जानकारी यहाँ: http://tools.android.com/tech-docs/android-ndk-preview


android.useDeprecatedNdk=true




1

नक्सोस ने जो कहा, उस पर विस्तार करने के लिए (मुझे सही दिशा में भेजने के लिए धन्यवाद नक्सोस!), मैंने हाल ही में जारी एनडीके उदाहरणों से काफी कुछ सीखा है और इसी तरह के सवाल का जवाब यहां पोस्ट किया है।

एंड्रॉइड ग्रैडल प्लगइन 0.7 के साथ एनडीके को कैसे कॉन्फ़िगर करें

इस पोस्ट में विभिन्न आर्किटेक्चर के साथ-साथ बिल्ड.ग्रेड स्क्रिप्ट को सीधे एनडीके समर्थन जोड़ने के तरीके के बारे में जानकारी के लिए आपके ऐप में पूर्वनिर्मित देशी पुस्तकालयों को जोड़ने पर पूरा विवरण है। अधिकांश भाग के लिए, आपको ज़िप के आसपास काम करने और अब कॉपी करने की आवश्यकता नहीं होनी चाहिए।


1

यहां वे चरण दिए गए हैं, जिनका उपयोग मैंने एनडीके को अपने एंड्रॉइड स्टूडियो प्रोजेक्ट में काम करने के लिए किया था। मैंने इस ट्यूटोरियल का उपयोग मेरी मदद करने के लिए किया https://software.intel.com/en-us/videos/use-the-ndk-with-android-studio

NDK का उपयोग करने के लिए आपको local.properties में NDK लाइन जोड़ना होगा। तो अपने sdk.dir के तहत जोड़ें

ndk.dir=C\:\\MyPathToMyNDK\ndk

मेरे ऐप्स में बिल्ड.ग्रेडल के पास निम्नलिखित कोड हैं

        ndk {
            moduleName "myLib"
            ldLibs "log"
            stl "gnustl_shared"
            cFlags "-std=c++11 -frtti -fexceptions -pthread"
        }

मॉड्यूलनाम वह नाम है जिसे आप अपना मूल कोड देना चाहते हैं। मेरा मानना ​​है कि यह साझा पुस्तकालय कहा जाएगा। ldLibs मुझे LogCat में प्रवेश करने की अनुमति देता है, stl वह stl है जिसे आप आयात करना चाहते हैं। बहुत सारे विकल्प हैं, जैसे कि ग्रहण एनडीके। ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cFlags अभी भी मेरे लिए एक निश्चित मात्रा में काला जादू हैं। मुझे सभी विकल्पों के लिए एक अच्छा स्रोत नहीं मिला है और वे मुझे क्या देते हैं। StackOverflow के आसपास कुछ भी आप की जरूरत के लिए खोजें, वह है जहाँ मैं इसे पाया है। मुझे पता है कि c ++ 11 मुझे नए c ++ 11 मानक का उपयोग करने की अनुमति देता है।

यहाँ एक उदाहरण है कि कैसे मैं लॉग कोड से मूल कोड में लॉग इन करता हूं

__android_log_print(ANDROID_LOG_DEBUG, "TestApp", "Adding - String %d has a field name of %s and a value of %s", i, lKeyUTF8.c_str(), lValueUTF8.c_str());

1

ग्रहण से एंड्रॉइड स्टूडियो में प्रोजेक्ट कॉन्फ़िगर करें : आपको एक्सेल में निर्यात किए बिना ग्रहण स्टूडियो प्रोजेक्ट को एंड्रॉइड स्टूडियो में आयात करना होगा और यह काम करता है, आपको स्थानीय में भी ndk का रास्ता जोड़ना होगा । यदि आप त्रुटि दिखाते हैं , तो जोड़ें

sourceSets.main {
        jniLibs.srcDir 'src/main/libs' 
        jni.srcDirs = [] //disable automatic ndk-build callenter code here
    }

में build.gradle फ़ाइल तो jni फ़ोल्डर और फ़ाइल का उपयोग कर टर्मिनल बनाने और चलाने के लिए यह काम करेगा


1
देखिए मेरा खुद का जवाब। यह वह वर्कअराउंड है जिसका मैं वर्तमान में उपयोग कर रहा हूं लेकिन यह वास्तव में समाधान नहीं है।
प्लैथथोस

1

अब जब एंड्रॉइड स्टूडियो स्थिर चैनल में है, तो एंड्रॉइड-एनडीके नमूने चलाने के लिए यह बहुत सीधा है । ये नमूने ndk प्रयोगात्मक प्लगइन का उपयोग करते हैं और Android NDK ऑनलाइन प्रलेखन से जुड़े लोगों की तुलना में नए हैं। एक बार जब आप जानते हैं कि वे काम करते हैं तो आप build.gradle, local.properties और gradle-wrapper.properties फ़ाइलों का अध्ययन कर सकते हैं और तदनुसार अपनी परियोजना को संशोधित कर सकते हैं। निम्नलिखित उन्हें काम करवाने के चरण हैं।

  1. सेटिंग्स, उपस्थिति और व्यवहार, सिस्टम सेटिंग्स, एंड्रॉइड एसडीके पर जाएं, एसडीके टूल टैब का चयन करें, और सूची के निचले भाग में एंड्रॉइड एनडीके संस्करण 1.0.0 की जांच करें। यह NDK डाउनलोड करेगा।

  2. नए डाउनलोड किए गए एनडीके के स्थान को इंगित करें। ध्यान दें कि इसे sdk / ndk-बंडल निर्देशिका में रखा जाएगा। फ़ाइल, प्रोजेक्ट स्ट्रक्चर, एसडीके लोकेशन (बाईं ओर) का चयन करके और एंड्रॉइड एनडीके स्थान के तहत एक पथ की आपूर्ति करके ऐसा करें। यह स्थानीय के समान ndk प्रविष्टि जोड़ेगा।

    Mac / Linux: ndk.dir = / Android / sdk /
    ndk- बंडल विंडोज: ndk.dir = C: \ Android \ sdk \ ndk-बंडल

मैंने gles3gni, देशी-कोडेक और बिल्डर को छोड़कर, इस तरह से रिपॉजिटरी में सभी परियोजनाओं को सफलतापूर्वक बनाया और तैनात किया है। मैं निम्नलिखित का उपयोग कर रहा हूं:

Android Studio 1.3 बिल्ड AI-141.2117773
Android -ndk नमूने 28 जुलाई, 2015 को प्रकाशित (ऊपर लिंक)
एसडीके टूल्स 24.3.3
NDK r10e C: \ Android \ sdk \ ndk- बंडल ग्रेडल
2.5
ग्रेडल प्लगइन 0.2.0
विंडोज 8.1 64 बिट में निकाला गया ।


1

NDK बिल्ड और ग्रेडल (मूल)

आम तौर पर NDK के साथ निर्माण करना उतना ही सरल है जितना कि ndkBuild पथ को Android.mk या CMakeLists.txt के लिए cmake पथ निर्दिष्ट करना। मैं पुराने Android.mk पर CMake की सलाह देता हूं क्योंकि Android Studio का C / C ++ सपोर्ट CLion पर आधारित है और यह CMake को अपने प्रोजेक्ट प्रारूप के रूप में उपयोग करता है। मेरे अनुभव में यह बड़ी परियोजनाओं पर IDE को अधिक उत्तरदायी बनाने के लिए गया है। आपके प्रोजेक्ट में संकलित हर चीज को एपीके में स्वचालित रूप से बनाया और कॉपी किया जाएगा।

apply plugin: 'com.android.library'

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
            // 64-bit support requires an Android API level higher than 19; Namely 21 and higher
            //abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE'

            }
        }
    }

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

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

प्रोजेक्ट में पूर्वनिर्मित लाइब्रेरी जोड़ना (उन्नत)

आपके NDK बिल्ड में स्टेटिक लाइब्रेरी (.A) को स्वचालित रूप से शामिल किया जाएगा, लेकिन प्री-बिल्ड डायनेमिक लाइब्रेरी (.so) को इसमें रखा जाना होगा jniLibs। इसका उपयोग करके कॉन्फ़िगर किया जा सकता है sourceSets, लेकिन आपको मानक को अपनाना चाहिए। build.gradleजब आप पूर्वनिर्मित पुस्तकालयों को शामिल करते हैं तो आपको किसी भी अतिरिक्त कमांड की आवश्यकता नहीं होती है ।

का लेआउट jniLibs

आप Android Gradle Plugin User Guide में संरचना के बारे में अधिक जानकारी प्राप्त कर सकते हैं ।

|--app:
|--|--build.gradle
|--|--src:
|--|--|--main
|--|--|--|--java
|--|--|--|--jni
|--|--|--|--|--CMakeLists.txt
|--|--|--|--jniLibs
|--|--|--|--|--armeabi
|--|--|--|--|--|--.so Files
|--|--|--|--|--armeabi-v7a
|--|--|--|--|--|--.so Files
|--|--|--|--|--x86
|--|--|--|--|--|--.so Files

आप तब परिणाम को सत्यापित कर सकते हैं एपीके में आपकी .so फाइलें होती हैं, आमतौर पर सामग्री की सूची build/outputs/apk/का उपयोग करके unzip -l myApp.apk

साझा पुस्तकालयों का निर्माण

यदि आप NDK में एक साझा पुस्तकालय का निर्माण कर रहे हैं तो आपको आगे कुछ करने की आवश्यकता नहीं है। यह एपीके में सही ढंग से बंडल किया जाएगा।


0

बस इस लाइनों को ऐप में जोड़ें build.gradle

dependencies {
    ...
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}

task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/armeabi/'
}

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

मुझे लगता है कि jniLibs.srcDirs का दृष्टिकोण इस की तुलना में साफ है क्योंकि आप abiFilter / जायके का उपयोग कर सकते हैं लेकिन आपका दृष्टिकोण भी काम करना चाहिए।
प्लासथोस

0

अब मैं इतनी सफलता लोड कर सकते हैं!

1.dso .so फ़ाइल इस पथ पर

Project:

| --src | - | - | - | - | - | - जावा | - | - | - | --जनिएलएस | - | - | - | - | - परमीबी | - | - | | | - | - | - |। तो फ़ाइलें

2. इस कोड को gradle.build में जोड़ें

android {
splits {
    abi {
        enable true
        reset()
        include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
        universalApk false
    }
}

}

3।System.loadLibrary("yousoname");

  1. आपके लिए अच्छा है, यह ग्रेडल 1.2.3 के साथ ठीक है

0
  1. यदि आपका प्रोजेक्ट ग्रहण से निर्यात किया गया है, तो कोड फ़ाइल में नीचे जोड़ दें e

    android {
       sourceSets{
            main{
               jniLibs.srcDir['libs']  
          }  
        }
    }

2.अगर आप एंड्रॉइड स्टूडियो में एक प्रोजेक्ट बनाते हैं:

src / main / ni में jniLibs नाम का फोल्डर बनाएं और अपनी * .so फाइलें jniLibs फोल्डर में डालें।

और कोड को अपनी श्रेणी फ़ाइल में नीचे कॉपी करें in

android {
    sourceSets{  
       main{  
         jniLibs.srcDir['jniLibs']  
      }  
    }
}

0

जबकि मेरा मानना ​​है कि SJoshi (oracle guy) के पास सबसे पूर्ण उत्तर है, SWIG प्रोजेक्ट एक विशेष मामला है, जो दिलचस्प और उपयोगी है, लेकिन अधिकांश उन परियोजनाओं के लिए सामान्यीकृत नहीं है जिन्होंने मानक SDK चींटी आधारित परियोजनाओं के साथ अच्छा किया है + NDK। हम सभी अब सबसे अधिक संभावना एंड्रॉइड स्टूडियो का उपयोग करना चाहते हैं, या मोबाइल के लिए अधिक सीआई फ्रेंडली बिल्ड टूलचैन चाहते हैं, जो सैद्धांतिक रूप से पेश करता है।

मैंने अपना दृष्टिकोण पोस्ट किया है, कहीं से उधार लिया है (मैंने एसओ पर यह पाया, लेकिन ऐप बिल्ड के लिए एक जिस्ट पोस्ट किया ।ग्रेड: https://gist.github.com/truedat101/c45ff2b69e91d5c8c8c7962d4b96e841 )। संक्षेप में, मैं निम्नलिखित सलाह देता हूं:

  • अपनी परियोजना को नवीनतम ग्रेडल बिल्ड में अपग्रेड न करें
  • अपने प्रोजेक्ट रूट में com.android.tools.build:gradle:1.5.0 का उपयोग करें
  • अपने ऐप प्रोजेक्ट में com.android.application का उपयोग करें
  • सुनिश्चित करें कि gradle.properties में है: android.useDeprecatedNdk = true (मामले में यह शिकायत है)
  • उपरोक्त दृष्टिकोण का उपयोग यह सुनिश्चित करने के लिए करें कि Android.mk फ़ाइलों को बनाने के आपके घंटे और प्रयास दूर नहीं होंगे। आप नियंत्रण करते हैं कि कौन सा लक्ष्य आर्क (एस) के निर्माण के लिए है। और ये निर्देश विंडोज उपयोगकर्ताओं के लिए दयालु हैं, जिन्हें सैद्धांतिक रूप से विशेष मुद्दों के बिना खिड़कियों पर निर्माण करने में सक्षम होना चाहिए।

एंड्रॉइड के लिए ग्रैडल मेरी राय में एक गड़बड़ रहा है, जितना कि मुझे उधार ली गई मावेन अवधारणाओं और एक परियोजना के लिए निर्देशिकाओं की राय संरचना पसंद है। यह NDK फीचर लगभग 3+ वर्षों से "जल्द ही आ रहा है"।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.