Android stüdyosu, sürüm ve NDK


153

Bu sınıf ve Android Studio desteğinde çok yeniyim. Dışa aktarma seçeneğini kullanarak android projemi derecelendirmeye dönüştürmeyi başardım.

Ancak bazı belgeleri veya başlangıç ​​noktası nasıl NDK yapı çakmak yapı sürecine entegre etmek arıyorum.

Mümkünse, yapı ikili dosyalarını (.so dosyaları) varlık dizinine kopyalayan bir tür "after" aşamasına da ihtiyacım var.


Cevabımı aşağıdaki linke gönderdim stackoverflow.com/questions/20900814/…
Ahmad Ali Nasir

24
Yeni okuyucular: Bu sorunun başlangıçta Android Studio beta döneminde sorulduğunu unutmayın; cevap zaman içinde değişti. Cevaplarda belirtilen Gradle sürümüne ve cevapların gerçekten ne zaman yayınlandığına dikkat edin.
Sean Beach

Bir şey gerçekten değişirse, durumu yeniden düzenlemek için soruyu düzenleyeceğim
plaisthos

Kanarya kanalındaki Android Studio 1.3, NDK'yı tamamen destekler. Referans: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 Haziran 2015: Android Studio 1.3 Beta sürümü artık beta kanalında! Maalesef, bu derleme henüz C / C ++ desteği içermiyor; Kaynak: tools.android.com/recent/androidstudio13betaavailable
fastr.de

Yanıtlar:


85

Entegrasyonun ilk sürümünü 1.3'te önizleme olarak yayınladık: http://tools.android.com/tech-docs/android-ndk-preview

1.3 tamamlandıktan sonra bile entegrasyon bir önizleme olarak kalacaktır. Ne zaman kesinleşeceği konusunda mevcut ETA yok (2015/07/10 itibariyle).

Daha fazla bilgi burada: http://tools.android.com/tech-docs/android-ndk-preview


2
Android Studio (ve Gradle desteği) altında hata ayıklama ile NDK ve komut tamamlama kullanabilseydim harika olurdu
powder366

1
@GREnvoy - Android stüdyosunda doğru NDK oluşturucusunu nasıl yapılandırabiliriz? Bana adımları atabilir misin? :)
Shravan

7
@DirtyBeach Neden eski? Studio'da hala NDK'nin bir entegrasyonu yok. Bunun üzerinde çalışıyoruz ama şu anda ETA yok.
Xavier Ducrohet

2
Benim eylemim "entegrasyonu" nasıl tanımladığımı temel alıyordu. Ben hiçbiri fantastik çözümler olmasa da, şu anda var olan "NDK'yı gradle ile kullanmanın bir yolu" anlamına geldiğini anladım. Ancak, yorumunuza dayanarak, ekibinizin gerçek bir entegrasyonun ne olabileceği konusunda aklında başka bir şey var gibi görünüyor. Önceki ifademi geri çekiyorum.
Sean Beach

2
NDK entegrasyonu Google IO 2015 sırasında duyuruldu. Android Studio 1.3'te mevcut (önizleme yakında indirilebilir. Kullanılabilir olduğunda bir bağlantı yayınlayacağım).
Cypress Frankenfeld

43

GÜNCELLEME: NDK destekli Android Studio çıktı: http://tools.android.com/tech-docs/android-ndk-preview

Bir komut dosyası oluşturmak için aşağıdaki sınıflandırma çözümü çalışmalıdır:

Oluşturma komut dosyamı kullanıyorum ve dosyama eklendi (Çalışmak için görünüyor 0.8+): Bu, aşağıdaki çözümle eşdeğer gibi görünüyor (ancak gradle dosyasında daha güzel görünüyor):

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

Dizin yoksa veya .sodosya içermiyorsa derleme maalesef başarısız olmaz .


5
Bu artık yeni Android Studio sürümü ile çalışmaz, geçici çözüm?
powder366

@ powder366 Cevabımı görün.
Leandros

2
Bir Groovy büyü bit: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Yardımınız için teşekkürler!
trnl

Android Studio 0.8.9 için prosedür nedir
Pandiri Deepak

1
@plaisthos Doğru yönü gösterdiğin için çok teşekkürler! Gradle betiğindeki ikinci satır, jni.srcDirs = [] //disable automatic ndk-buildAndroid Studio'nun C / C ++ kaynak kodunu yeniden oluşturmasını engelleyeceğinden çok önemlidir. Gönderinizi görene kadar iki gündür bunu anlamaya çalışıyorum ve bu sorunumu çözdü. NDK derlemesinin Android.mk komut satırı makefile tarafından ayrı ayrı inşa edildiğini düşünüyorum.
tonga

40

Android Studio'nun 1.0'a güncellenmesiyle NDK araç zinciri desteği son derece gelişti ( not: yeni deneysel Gradle eklentisi ve Android Studio 1.5 ile kullanımı görmek için lütfen bu yazının altındaki güncellemelerimi okuyun ).

Android Studio ve NDK, modülünüzün build.gradle dosyasında bir ndk {} bloğu oluşturmanız ve kaynak dosyalarınızı (module) / src / main / jni dizinine ayarlamanız için yeterince iyi bir şekilde entegre edilmiştir. bitmiş!

Komut satırından artık ndk-build yok.

Bununla ilgili her şeyi blog gönderime yazdım: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

Dikkat çeken noktalar:

Burada bilmeniz gereken iki şey var. Varsayılan olarak, Android uygulamasına yüklenmesini istediğiniz harici kütüphaneleriniz varsa, bunlar varsayılan olarak (module) / src / main / jniLibs içinde aranır. Modülünüzün build.gradle içindeki sourceSets.main.jniLibs.srcDirs ayarını kullanarak bunu değiştirebilirsiniz. Hedeflediğiniz her mimari için kitaplık içeren bir alt dizine ihtiyacınız olacaktır (örn. X86, kol, mips, arm64-v8a vb.)

NDK araç zinciri tarafından varsayılan olarak derlenmesini istediğiniz kod, (module) / src / main / jni dizininde bulunur ve yukarıdakine benzer şekilde, modülünüzün build.gradle içindeki sourceSets.main.jni.srcDirs öğesini ayarlayarak değiştirebilirsiniz.

ve bunu modülünüzün build.gradle dosyasına koyun:

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
}

Bu, C ++ kodunuzu derleme işlemidir, oradan yüklemeniz ve paketleyicileri oluşturmanız gerekir - ancak sorunuzdan yola çıkarak, tüm bunları nasıl yapacağınızı zaten biliyorsunuz, bu yüzden yeniden hash etmeyeceğim.

Ayrıca, bu örneğin bir Github kopyasını buraya yerleştirdim: http://github.com/sureshjoshi/android-ndk-swig-example

GÜNCELLEME: 14 Haziran 2015

Android Studio 1.3 çıktığında, JetBrains CLion eklentisi aracılığıyla C ++ için daha iyi destek olmalıdır. Şu anda Android Studio içinden Java ve C ++ geliştirmeye izin vereceği varsayımı altındayım; ancak Gradle NDK bölümünü yukarıda belirttiğim gibi kullanmamız gerektiğini düşünüyorum. Ayrıca, CLion bunları otomatik olarak yapmayacaksa, Java <-> C ++ sarmalayıcı dosyaları yazmaya hala ihtiyaç olacağını düşünüyorum.

GÜNCELLEME: 5 Ocak 2016

Blogumu ve Github Repo'yu (geliştirme dalında) en son deneysel Gradle eklentisi (0.6.0-alpha3) ile Android Studio 1.5'i kullanacak şekilde güncelledim.

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

NDK bölümü için Gradle derlemesi şu şekilde görünüyor:

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
}

Ayrıca, oldukça garip bir şekilde, Android Studio 'yerli' anahtar kelimeyi kullanarak C ++ - Java tarafından oluşturulan sarmalayıcıları için otomatik tamamlama özelliğine sahiptir:

C ++ otomatik tamamlama örneği - Java sarmalayıcısı

Ancak, tamamen pembe değil ... Otomatik olarak kod oluşturmak için bir kitaplığı sarmak için SWIG kullanıyorsanız ve daha sonra yerel anahtar kelime otomatik oluşturmayı kullanmaya çalışırsanız, kodu Swig _wrap'nizde yanlış yere koyar .cxx dosyası ... Yani "extern C" bloğuna taşımanız gerekir:

Java sarıcı doğru konuma taşındı

GÜNCELLEME: 15 Ekim 2017

Android Studio 2.2'den sonra Gradle ve CMake aracılığıyla NDK araç zinciri için esasen 'yerli' (pun yok) desteğe sahip olduğundan bahsetmezsem hatırlayacağım. Şimdi, yeni bir proje oluşturduğunuzda, C ++ desteğini seçmeniz yeterlidir.

Yine de kendi JNI katman kodunuzu oluşturmanız veya yukarıda bahsettiğim SWIG tekniğini kullanmanız gerekecek, ancak Android projesinde bir C ++ iskelesi artık önemsiz.

CMakeLists dosyasındaki değişiklikler (C ++ kaynak dosyalarınızı yerleştirdiğiniz yer) Android Studio tarafından alınır ve ilişkili kitaplıkları otomatik olarak yeniden derler.


1
* .so (modül) / src / main / jniLibs
fawkes

NDEBUG neden Android Studio kullanırken hata ayıklama yapılarında bile ayarlanır
pt123

35

Google IO 2015'te Google, Android Studio 1.3'te tam NDK entegrasyonunu duyurdu.

Artık önizleme dışında ve herkese açık: https://developer.android.com/studio/projects/add-native-code.html

Eski cevap: Proje kaynaklarınızda ndk-buildbir jnidizin varsa Gradle otomatik olarak çağırır .

Bu Android studio 0.5.9 (kanarya yapı) üzerinde çalışıyor.

  1. NDK'yı indirin

  2. Ya eklemek ANDROID_NDK_HOMEiçin ortam değişkenleri veya eklemek ndk.dir=/path/to/ndkadresinden Müşteri local.propertiesAndroid Studio projesinde. Bu, Android stüdyosunun ndk'yi otomatik olarak çalıştırmasını sağlar.

  3. Bir ndk projesi örneği görmek için en son sınıf örneği projeleri indirin . (Sayfanın altındalar). İyi bir örnek proje ndkJniLib.

  4. gradle.buildNDK örnek projelerinden kopyalayın . Bunun gibi bir şey olacak. Bu gradle.build, her mimari için farklı bir apk oluşturur. Bölmeyi kullanarak istediğiniz mimariyi seçmelisiniz build variants. varyant bölmesini oluştur

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

Bunun Android.mk ve Application.mk dosyalarınızı yok sayacağını unutmayın. Geçici bir çözüm olarak, gradle'dan atuomatic ndk-build çağrısını devre dışı bırakmasını söyleyebilir, ardından ndk kaynakları için dizini manuel olarak belirtebilirsiniz.

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
}

Ayrıca, otomatik aramayı devre dışı bıraktığınız için büyük olasılıkla sınıf oluşturma komut dosyanızda ndk-build'i çağırmak isteyeceksiniz.

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

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

Evet. Ancak bu yalnızca Unix platformları altında çalışır ve çok basit ndk yapılandırması / makefiles'lerinden daha karmaşıksanız da sınırlıdır.
plaisthos

Evet, sınıf oluşturma dosyasında ayarlayabileceğiniz sınırlı şeyler için makefiles'i otomatik olarak oluşturur, ancak bir geçici çözüm vardır. Cevabıma ekledim.
Cypress Frankenfeld

1
Ndk-build çağrısı, yalnızca Android Studio'da değil, komut satırında çalışır.
Cameron Lowell Palmer

Bu en son cevap olmasa da, muhtemelen en doğru yanıt gibi görünüyor. 3. adıma özellikle dikkat edin: " En yeni sınıf örnek projelerini indirin ".
Sean Beach

4
Ben ide içinde c / c ++ dosyaları düzenleyebilirsiniz böylece src dir devre dışı bırakmak yerine bu kesmek kullanıntasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
sherpya

23

Ben buldum "gradle 1.11 com.android.tools.build:gradle:0.9.+" şimdi inşa öncesi ndk destekler, sadece * .so dir src / main / jniLibs koyabilirsiniz. kepçe inşa ederken ndk doğru yere paketleyecektir.

işte benim projem

Proje:
| --src
| - | --main
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | -. So dosyaları
| Libs
| - | --other.jar


16

Şu andan itibaren (Android Studio v0.8.6) oldukça basit. "Merhaba dünya" türü bir uygulama oluşturma adımları şunlardır:

  1. Android NDK'yi indirin ve kök klasörü aklı başında bir yere koyun - belki de SDK klasörü ile aynı konuma.

  2. local.propertiesDosyanıza aşağıdakileri ekleyin : ndk.dir=<path-to-ndk>

  3. Satırdan defaultConfighemen sonra, kapağın içindeki build.gradle dosyanıza aşağıdakileri ekleyin versionName:ndk { moduleName="hello-world" }

  4. Uygulama modülünüzün maindizininde adlı yeni bir klasör oluşturun jni.

  5. Bu klasörde, hello-world.caşağıda göreceğiniz adlı bir dosya oluşturun .

  6. Activityİçinde bir yöntemin nasıl çağrılacağına dair bir örnek (veya bir işlev mi?) İçin aşağıdaki örnek koda bakın 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'])
}

Çok benzer bir uygulamanın tam kaynak kodunu burada bulabilirsiniz (eksi NDK).


Şu anki projemde anlatıldığı gibi yapıyorum ama NDK işleri hala kurulmuyor. Herhangi bir fikir? Diğer her şeyi inşa ediyor gibi görünüyor, ama sadece jni şeyler atlıyor.
alice.harrison

@NannuoLei teşekkürler, denedim ama .so üretilmeyen bir sorun alıyorum. Diğer her şey işe yarıyor gibi görünüyor, ancak apkg'ı emülatörde çalıştırdığımda, paylaşılan nesneyi yükleyemediğinden şikayet ediyor.
aaa90210

@ aaa90210 öykünücünüz bir x86 görüntüsünü temel alıyor mu? Varsayılan olarak NDK sadece bir ARMEABI kütüphanesi üretecektir, bir x86 görüntüsü oluşturmak istiyorsanız bu satırı Application.mk'ye ekleyebilirsiniz: APP_ABI: = armeabi x86
Leo, Monica

1
benimle çalıştı. Not: Bu cevabı gören herkes Java_me_mattlogan_ndktest_MainActivity_stringFromJNI, kendi cevabınızı değiştirmeyi unutmayın :)
AbdulMomen عبدالمؤمن

8

Unix kullanıyorsanız son sürüm (0.8) ndk-build ekler. Nasıl ekleyeceğiniz aşağıda açıklanmıştır:

android.ndk {
    moduleName "libraw"
}

JNI'yi 'src / main / jni' altında bulmayı bekler, aksi takdirde aşağıdakilerle tanımlayabilirsiniz:

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

Sürüm 0.8 ile 28 Ocak 2014 itibariyle yapı pencerelerde bozuk, yapıyı şu şekilde devre dışı bırakmanız gerekir:

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

1
Bu özellikle ilgili herhangi bir belge var mı? Ben bulamadım. Şu anda Android.mk/Application.mk'mi tamamen görmezden geliyor gibi görünüyor.
plaisthos

Hiç bulamadım. Yarı pişmiş yapıya sıkışmış olabilir. Ben sadece unix ndk-build betiği çağırmaya çalışırken başarısız olduğunu teyit edebilirim. Bunu derlemek için derlemek için başka bir neden yoktur. Unix'te misin?
Anthony


aslında önceden oluşturulmuş * .so dosyalarını jniLibs.srcDirs içinde bulmayı bekliyor
Alpine

İnşa kütüphaneleri gerektiriyorsa kesinlikle gerekli olmayan ndk-build çağrısı çökmesine dayanarak katılmıyorum. Şu anda Linux vm için zamanım olmadığı için onaylayamıyorum.
Anthony

7

Zarif bir geçici çözüm https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J içinde gösterilir .

Temel olarak "lib / armeabi / yourlib.so" içeren bir kavanoz oluşturur ve daha sonra kavanozları yapıya dahil edersiniz.


Evet. Bu, yalnızca kodunuzu sık sık değiştirmediğinizde işe yarar. Ve depoya ikili jar dosyaları eklemeniz gerekecek. Aksi takdirde, anında bir kavanoz oluşturan bir yapı komut dosyası ile sonuçlanırsınız.
plaisthos

1
Ben ettik Android'in Merhaba-JNI'yı değiştirilmiş bir örnek bir ile basit bash komut sarar o ndk-buildoluşturur .jarher biri için s .sobu acıyı hafifletmek için gradle en oluşturma yolundaki ve yerler onlar. Bunu kontrol et.
dbro

4

Kolayca derlenmiş .sodosyaların paketlenmesini otomatikleştiren iyi bir cevap başka bir (kapalı) iplikte verilir . Bunu çalıştırabilmek için çizgiyi değiştirmek zorunda kaldım:

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

içine:

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

Bu değişiklik olmadan .sodosyalar bulunamamıştır ve bu nedenle onları paketleme görevi asla çalışmaz.


Güncelleme: lütfen daha yeni Android Stüdyolarında (en azından 1.5'te) yerel kodun daha iyi bir şekilde dahil edildiğini ve kodunuzu paketlemek için bu ayrı görevi yapmanın gerekli olmadığını unutmayın.
HYS

4

@Plaisthos'un cevabı en son gradle versiyonunda kırıldı, ancak yine de bunu yapmanın bir yolu var. native-libsProje dizininizin kökünde bir dizin oluşturun ve tüm kütüphanelerimizi bu dizine kopyalayın.

Build.gradle dosyasına aşağıdaki satırları ekleyin. İnşa et ve mutlu ol.

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

Bu gradle gelen android-ndk kullanarak oluşturmak için kullandığım kod. Bunun için ndk dizin yolunu ekleyin gradle.properties. ekleyebilir ndkdir=/home/user/android-ndk-r9dve bir klasördeki tüm jni dosyaları koymak nativeiçinde src/main/kod aşağıda yayınlanmıştır dan gördüğünüz gibi. Normal liblerde olduğu gibi kullanabileceğiniz doğal kütleli kavanoz oluşturacaktır.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

Yerel dropbox kitaplıklarını derlemek için aşağıdaki kodu kullandım, Android Studio v1.1 kullanıyorum.

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


1

Naxos'un söylediklerini genişletmek için (Beni doğru yönde gönderdiğiniz için teşekkürler Naxos!), Yakın zamanda yayınlanan NDK örneklerinden biraz öğrendim ve benzer bir soruya burada bir cevap gönderdim.

Android Gradle eklentisi 0.7 ile NDK nasıl yapılandırılır

Bu gönderi, çeşitli mimariler için önceden oluşturulmuş yerel kütüphaneleri uygulamanıza bağlama hakkında tüm ayrıntıların yanı sıra NDK desteğini doğrudan build.gradle komut dosyasına nasıl ekleyeceğiniz hakkında bilgi içerir. Çoğunlukla, artık zip etrafında kopyalama ve kopyalama yapmanıza gerek yok.


1

İşte NDK'nın Android Studio projemde çalışmasını sağlamak için kullandığım adımlar. Bu öğreticiyi bana yardım etmek için kullandım https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

NDK kullanmak için local.properties dosyasına bir NDK satırı eklemelisiniz. Yani sdk.dir altında eklemek

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

Benim apps build.gradle aşağıdaki kodu var

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

moduleName yerel kodunuzu vermek istediğiniz addır. Paylaşılan kütüphanenin bu şekilde olacağına inanıyorum. ldLibs LogCat oturumu açmak için bana izin verir, stl almak istediğiniz stl olduğunu. Eclipse NDK ile aynı çok seçenek var. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cFlags hala benim için belirli bir miktar kara büyü. Tüm seçenekler ve bana verdikleri şeyler için iyi bir kaynak bulamadım. İhtiyacınız olan her şeyi StackOverflow'da arayın, bulduğum yer burası. C ++ 11 yeni c ++ 11 standardını kullanmama izin verdiğini biliyorum.

İşte yerel koddan LogCat'e nasıl giriş yaptığımın bir örneği

__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

içinde yapılandırmak projesi android stüdyoda Tutulma: Eğer gradle ihracat olmadan android stüdyoya Tutulma ndk projeyi ithal etmek zorunda ve aynı zamanda içinde NDK yolunu eklemeniz gerekir, işleri local.properties gösterileri hata sonra eklerseniz,

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

içinde build.gradle dosyası daha sonra oluşturmak jni terminali kullanarak klasör ve dosya ve işe yarayacak çalıştırmak


1
Bak kendi cevabımı gör. Bu şu anda kullandığım geçici çözüm ama gerçekten bir çözüm değil.
plaisthos

1

Android Studio artık kararlı kanalda olduğundan, android-ndk örneklerinin çalışmasını sağlamak oldukça basittir . Bu örnekler ndk deneysel eklentisini kullanır ve Android NDK çevrimiçi belgelerinden bağlantılı olanlardan daha yenidir. Çalıştıklarını öğrendikten sonra build.gradle, local.properties ve gradle-wrapper.properties dosyalarını inceleyebilir ve projenizi buna göre değiştirebilirsiniz. Onları çalıştıracak adımlar aşağıdadır.

  1. Ayarlar, Görünüm ve Davranış, Sistem Ayarları, Android SDK'ya gidin, SDK Araçları sekmesini seçin ve listenin altındaki Android NDK sürüm 1.0.0'ı kontrol edin. Bu NDK'yı indirecektir.

  2. Yeni indirilen NDK'nin yerini gösterin. Bunun sdk / ndk-bundle dizinine yerleştirileceğini unutmayın. Bunu Dosya, Proje Yapısı, SDK Konumu (solda) seçerek ve Android NDK konumu altında bir yol sağlayarak yapın. Bu, local.properties'e şuna benzer bir ndk girişi ekleyecektir:

    Mac / Linux: ndk.dir = / Android / sdk /
    ndk -bundle Windows: ndk.dir = C: \ Android \ sdk \ ndk-bundle

Depodaki tüm projeleri başarıyla gles3gni, native-codec bileşeni ve builder dışında bu şekilde oluşturdum ve dağıttım. Aşağıdakileri kullanıyorum:

Android Studio 1.3, AI-141.2117773
android -ndk örnekleri 28 Temmuz 2015'te yayınlandı (yukarıdaki bağlantı)
SDK Araçları 24.3.3
NDK r10e, C: \ Android \ sdk \
ndk -bundle Gradle 2.5
Gradle eklentisi 0.2.0
Windows 8.1 64 bit


1

NDK Yapıları ve sınıflandırma (temel)

Genel olarak NDK ile oluşturmak, Android.mk'ye ndkBuild yolunu veya CMakeLists.txt yoluna cmake yolunu doğru bir şekilde belirtmek kadar basittir. Android Studio'nun C / C ++ desteği CLion'a dayalı olduğu ve proje biçimi olarak CMake'i kullandığı için CMake'i eski Android.mk üzerinden öneriyorum. Deneyimlerime göre bu, IDE'yi daha büyük projelerde daha duyarlı hale getirme eğilimindedir. Projenizde derlenen her şey otomatik olarak oluşturulacak ve APK'ya kopyalanacaktır.

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

Projeye önceden oluşturulmuş kitaplıklar ekleme (gelişmiş)

NDK derlemenizdeki statik kitaplıklar (.a) otomatik olarak dahil edilir, ancak önceden oluşturulmuş dinamik kitaplıkların (.so) yerleştirilmesi gerekir jniLibs. Bu, kullanılarak yapılandırılabilir sourceSets, ancak standardı benimsemeniz gerekir. Önceden build.gradleoluşturulmuş kitaplıkları eklerken herhangi bir ek komut GEREKMEZ .

Düzeni jniLibs

Yapıyla ilgili daha fazla bilgiyi Android Gradle Plugin Kullanıcı Kılavuzu'nda bulabilirsiniz .

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

Ardından, ortaya çıkan APK'nın , içeriği listelemek için build/outputs/apk/kullanarak genellikle altında bulunan .so dosyalarınızı içerdiğini doğrulayabilirsiniz unzip -l myApp.apk.

Paylaşılan kütüphaneler oluşturma

NDK'da paylaşılan bir kütüphane oluşturuyorsanız, başka bir şey yapmanız gerekmez. APK'da doğru bir şekilde paketlenecektir.


0

Bu satırları uygulamaya eklemeniz yeterlidir 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)
}

Ben abiFilter / tatlar kullanabilirsiniz çünkü jniLibs.srcDirs yaklaşım bundan daha temiz olduğunu düşünüyorum ama yaklaşımınız da çalışması gerekir.
plaisthos

0

Şimdi bu kadar başarılı olabilir!

1. .so dosyasını bu yola ekleyin

Project:

| --src | - | --main | - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - | - | - | -. dosyaları

2. bu kodu gradle.build dosyasına ekleyin

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

}

3.System.loadLibrary("yousoname");

  1. goodluck sizin için, bu kepçe 1.2.3 ile tamam

0
  1. Projeniz tutulmadan dışa aktarıldıysa, aşağıdaki kodları not dosyasına ekleyin :

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

2.Android stüdyosunda bir proje oluşturursanız:

src / main / , içinde jniLibs adlı bir klasör oluşturun ve * .so dosyalarınızı jniLibs klasörüne yerleştirin.

Ve gradle dosyanızda aşağıdaki kodu kopyalayın :

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

0

SJoshi'nin (oracle guy) en eksiksiz cevaba sahip olduğuna inanırken, SWIG projesi, ilginç ve kullanışlı, özel bir durum, ancak standart SDK karınca tabanlı projelerle başarılı olan projelerin çoğu için genelleştirilmemiş + NDK. Hepimiz şimdi büyük olasılıkla Android stüdyosunu kullanmak istiyoruz veya teorik olarak sunulan mobil cihazlar için daha fazla CI dostu bir yapı aracı zinciri istiyoruz.

Yaklaşımımı yayınladım, bir yerden ödünç aldım (bunu SO'da buldum, ancak uygulama build.gradle için bir özgeçmiş gönderdim: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). Özetle, aşağıdakileri tavsiye ederim:

  • Projenizi en yeni sınıf sürümüne yükseltmeyin
  • Proje kökünüzde com.android.tools.build:gradle:1.5.0 kullanın
  • Uygulama projenizde com.android.application kullanın
  • Gradle.properties öğesinin şunlara sahip olduğundan emin olun: android.useDeprecatedNdk = true (şikayet etmesi durumunda)
  • Android.mk dosyalarını oluşturmak için harcadığınız çalışma saatlerinin ve saatlerinin atılmamasını sağlamak için yukarıdaki yaklaşımı kullanın. Hangi hedeflerin oluşturulacağını siz kontrol edersiniz. Ve bu talimatlar, teorik olarak özel sorunlar olmadan pencereler üzerine inşa edebilmesi gereken Windows kullanıcılarına karşı naziktir.

Android için Gradle bence, ödünç alınan maven kavramlarını ve bir proje için dizinlerin görüşlü yapısını sevdiğim gibi bir karışıklık oldu. Bu NDK özelliği neredeyse 3 yıldan fazla bir süredir "yakında".

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.