Studio Android, gradle, dan NDK


153

Saya sangat baru dengan dukungan seluruh kelas dan Android Studio ini. Saya telah berhasil mengonversi proyek android saya menjadi bertahap menggunakan opsi ekspor.

Tetapi saya mencari beberapa dokumentasi atau titik awal bagaimana mengintegrasikan NDK build ke dalam proses gradle build.

Jika memungkinkan saya juga memerlukan semacam tahap "setelah" yang menyalin binari build (file .so) ke direktori aset.


Saya telah memposting jawaban saya di tautan yang disebutkan di bawah ini stackoverflow.com/questions/20900814/...
Ahmad Ali Nasir

24
Pembaca baru: Waspadai pertanyaan ini pada awalnya ditanyakan selama periode beta Android Studio; jawabannya telah berubah seiring waktu. Perhatikan versi Gradle yang disebutkan dalam jawaban, serta ketika jawaban itu benar-benar diposting.
Pantai Sean

Jika sesuatu benar-benar berubah, saya akan mengedit pertanyaan untuk menghubungkan kembali status
plaisthos

Android Studio 1.3 di saluran kenari sepenuhnya mendukung NDK. Referensi: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 Juni 2015: Android Studio 1.3 Beta sekarang tersedia di saluran beta! Maaf, build ini belum mengandung dukungan C / C ++; sumber: tools.android.com/recent/androidstudio13betaavailable
fastr.de

Jawaban:


85

Kami telah merilis versi pertama integrasi sebagai pratinjau di 1.3: http://tools.android.com/tech-docs/android-ndk-preview

Integrasi akan tetap menjadi pratinjau bahkan setelah 1,3 menjadi final. Tidak ada ETA saat ini tentang kapan akan final (per 2015/07/10).

Informasi lebih lanjut di sini: http://tools.android.com/tech-docs/android-ndk-preview


2
Akan lebih bagus jika saya bisa menggunakan NDK dan menyelesaikan perintah dengan debugging di bawah Android Studio (dan dukungan Gradle)
powder366

1
@GREnvoy - Bagaimana kami mengonfigurasi pembuat NDK yang tepat di Android studio? Bisakah Anda memberi saya langkah-langkahnya? :)
Shravan

7
@DirtyBeach Mengapa ini sudah usang? Masih belum ada integrasi dari NDK di Studio. Kami sedang mengerjakannya tetapi tidak ada ETA saat ini.
Xavier Ducrohet

2
Tindakan saya didasarkan pada bagaimana saya mendefinisikan "integrasi". Saya mengerti itu berarti "cara untuk menggunakan NDK dengan gradle" yang sekarang memang ada, meskipun tidak satupun dari mereka adalah solusi yang fantastis. Namun, berdasarkan komentar Anda, tampaknya tim Anda memiliki sesuatu yang lain dalam pikiran untuk apa integrasi yang sebenarnya. Saya menarik kembali pernyataan saya sebelumnya.
Pantai Sean

2
Integrasi NDK diumumkan selama Google IO 2015. Ini tersedia di Android Studio 1.3 (pratinjau dapat segera diunduh. Saya akan memposting tautan saat tersedia).
Cypress Frankenfeld

43

UPDATE: Android Studio dengan dukungan NDK sudah keluar sekarang: http://tools.android.com/tech-docs/android-ndk-preview

Untuk membangun dengan skrip, solusi gradle di bawah ini harus berfungsi:

Saya menggunakan skrip build saya dan ditambahkan ke file saya (Tampaknya berfungsi untuk 0.8+): Ini tampaknya setara dengan solusi di bawah ini (tetapi terlihat lebih bagus di file gradle):

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

Sayangnya, build tidak gagal jika direktori tidak ada atau tidak mengandung .sofile.


5
Ini tidak berfungsi lagi dengan versi Android Studio yang baru, solusinya?
powder366

@ powder366 Lihat jawaban saya.
Leandros

2
Sedikit dari Groovy sihir: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Terima kasih kawan atas bantuannya!
trnl

Bagaimana prosedur untuk android Studio 0.8.9
Pandiri Deepak

1
@plaisthos Terima kasih banyak untuk menunjukkan arah yang benar! Baris kedua dalam skrip gradle jni.srcDirs = [] //disable automatic ndk-buildsangat penting karena akan mencegah Android Studio membangun kembali kode sumber C / C ++. Saya telah mencoba mencari tahu ini selama dua hari sampai saya melihat posting Anda dan ini menyelesaikan masalah saya. Saya benar-benar berpikir NDK build lebih baik dibangun secara terpisah oleh makefile command line Android.mk saja, bukan dengan skrip gradle karena C / C ++ telah dibangun oleh Makefile selama lebih dari 40 tahun!
tonga

40

Dengan pembaruan Android Studio ke 1.0, dukungan toolchain NDK meningkat pesat ( catatan: baca pembaruan saya di bagian bawah posting ini untuk melihat penggunaan dengan plugin Gradle eksperimental baru dan Android Studio 1.5 ).

Android Studio dan NDK terintegrasi cukup baik sehingga Anda hanya perlu membuat blok ndk {} di build.gradle modul Anda, dan mengatur file sumber Anda ke dalam direktori (module) / src / main / jni - dan Anda selesai!

Tidak ada lagi ndk-build dari baris perintah.

Saya sudah menulis semua itu di posting blog saya di sini: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

Poin yang menonjol adalah:

Ada dua hal yang perlu Anda ketahui di sini. Secara default, jika Anda memiliki lib eksternal yang ingin Anda muat ke dalam aplikasi Android, mereka dicari di (modul) / src / main / jniLibs secara default. Anda dapat mengubahnya dengan menggunakan pengaturan sourceSets.main.jniLibs.srcDirs di build.gradle modul Anda. Anda memerlukan subdirektori dengan pustaka untuk setiap arsitektur yang Anda targetkan (mis. X86, arm, mips, arm64-v8a, dll ...)

Kode yang Anda ingin dikompilasi secara default oleh toolchain NDK akan berlokasi di (module) / src / main / jni dan mirip dengan di atas, Anda dapat mengubahnya dengan mengatur sourceSets.main.jni.srcDirs di build.gradle modul Anda.

dan letakkan ini di build.gradle modul Anda:

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
}

Itulah proses mengkompilasi kode C ++ Anda, dari sana Anda perlu memuatnya, dan membuat pembungkus - tetapi menilai dari pertanyaan Anda, Anda sudah tahu bagaimana melakukan semua itu, jadi saya tidak akan memotong kembali.

Juga, saya telah menempatkan repo Github dari contoh ini di sini: http://github.com/sureshjoshi/android-ndk-swig-example

PEMBARUAN: 14 Juni 2015

Ketika Android Studio 1.3 keluar, harus ada dukungan yang lebih baik untuk C ++ melalui plugin JetBrains CLion. Saya saat ini dengan asumsi bahwa ini akan memungkinkan pengembangan Java dan C ++ dari dalam Android Studio; namun saya pikir kita masih harus menggunakan bagian Gradle NDK seperti yang telah saya nyatakan di atas. Selain itu, saya pikir masih akan ada kebutuhan untuk menulis file wrapper Java <-> C ++, kecuali CLion akan melakukannya secara otomatis.

PEMBARUAN: 5 Januari 2016

Saya telah memperbarui blog saya dan repo Github (di cabang pengembangan) untuk menggunakan Android Studio 1.5 dengan plugin Gradle eksperimental terbaru (0.6.0-alpha3).

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

Bangunan Gradle untuk bagian NDK sekarang terlihat seperti ini:

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
}

Selain itu, cukup mengagumkan, Android Studio memiliki pelengkapan otomatis untuk C ++ - pembungkus yang dihasilkan Java menggunakan kata kunci 'asli':

Contoh lengkapi-otomatis C ++ - Java wrapper

Namun, itu tidak sepenuhnya menyenangkan ... Jika Anda menggunakan SWIG untuk membungkus pustaka untuk menghasilkan kode secara otomatis, dan kemudian mencoba menggunakan pembuatan kata kunci asli bawaan, itu akan menempatkan kode di tempat yang salah di Swig Anda _wrap File .cxx ... Jadi Anda perlu memindahkannya ke blok "extern C":

C ++ - Pembungkus Java dipindahkan ke lokasi yang benar

PEMBARUAN: 15 Oktober 2017

Saya akan lalai jika saya tidak menyebutkan bahwa Android Studio 2.2 dan seterusnya pada dasarnya memiliki dukungan 'asli' (tanpa kata-kata) untuk toolchain NDK melalui Gradle dan CMake. Sekarang, ketika Anda membuat proyek baru, cukup pilih dukungan C ++ dan Anda siap melakukannya.

Anda masih perlu membuat kode layer JNI Anda sendiri, atau menggunakan teknik SWIG yang saya sebutkan di atas, tetapi perancah C ++ dalam proyek Android sepele sekarang.

Perubahan pada file CMakeLists (yang merupakan tempat Anda meletakkan file sumber C ++) akan diambil oleh Android Studio, dan itu akan secara otomatis mengkompilasi ulang pustaka terkait.


1
letakkan * .so di (module) / src / main / jniLibs
fawkes

mengapa NDEBUG selalu diatur saat menggunakan Android Studio, bahkan pada debug build
pt123

35

Di Google IO 2015, Google mengumumkan integrasi penuh NDK di Android Studio 1.3.

Sekarang sudah keluar dari pratinjau, dan tersedia untuk semua orang: https://developer.android.com/studio/projects/add-native-code.html

Jawaban lama: Gradle secara otomatis menelepon ndk-buildjika Anda memiliki jnidirektori di sumber proyek Anda.

Ini bekerja di Android studio 0.5.9 (canary build).

  1. Unduh NDK

  2. Tambahkan ANDROID_NDK_HOMEke variabel lingkungan Anda atau tambahkan ndk.dir=/path/to/ndkke Anda local.propertiesdi proyek Android Studio Anda. Ini memungkinkan Android studio untuk menjalankan ndk secara otomatis.

  3. Unduh proyek sampel gradle terbaru untuk melihat contoh proyek ndk. (Mereka ada di bagian bawah halaman). Proyek sampel yang bagus adalah ndkJniLib.

  4. Salin gradle.builddari proyek sampel NDK. Ini akan terlihat seperti ini. Ini gradle.buildmenciptakan apk yang berbeda untuk setiap arsitektur. Anda harus memilih arsitektur yang Anda inginkan menggunakan build variantspanel. membangun panel varian

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

Perhatikan bahwa ini akan mengabaikan file Android.mk dan Application.mk Anda. Sebagai solusinya, Anda dapat memberitahu gradle untuk menonaktifkan panggilan ndk-build otomatis, lalu tentukan direktori untuk sumber ndk secara manual.

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
}

Selain itu, Anda mungkin ingin memanggil ndk-build di skrip gradle build Anda secara eksplisit, karena Anda baru saja menonaktifkan panggilan otomatis.

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

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

Iya. Tapi itu hanya berfungsi di bawah platform Unix dan juga terbatas jika Anda lebih kompleks daripada konfigurasi / makefile ndk sangat sederhana.
plaisthos

Ya, itu akan membuat secara otomatis file makefile untuk hal-hal terbatas yang dapat Anda atur di file gradle build, namun ada solusinya. Saya menambahkannya ke jawaban saya.
Cypress Frankenfeld

1
Panggilan ke ndk-build hanya akan bekerja di command-line bukan dari dalam Android Studio.
Cameron Lowell Palmer

Meskipun ini bukan jawaban yang paling baru, sepertinya ini yang paling akurat. Berikan perhatian khusus pada langkah 3: "Unduh proyek sampel gradle terbaru ".
Pantai Sean

4
Saya menggunakan peretasan ini alih-alih menonaktifkan src dir sehingga saya dapat mengedit file c / c ++ di dalam idetasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
sherpya

23

Saya menemukan "gradle 1.11 com.android.tools.build:gradle/0.9.+" mendukung pre-build ndk sekarang, Anda cukup meletakkan * .so di dir src / main / jniLibs. ketika membangun gradle akan mengemas ndk ke tempat yang tepat.

ini proyek saya

Proyek:
| --src
| - | - utama
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | -. jadi file
| --libs
| - | --other.jar


16

Sampai sekarang (Android Studio v0.8.6) cukup sederhana. Berikut adalah langkah-langkah untuk membuat aplikasi jenis "Hello world":

  1. Unduh Android NDK dan letakkan folder root di tempat yang waras - di lokasi yang sama dengan folder SDK, mungkin.

  2. Tambahkan yang berikut ke local.propertiesfile Anda : ndk.dir=<path-to-ndk>

  3. Tambahkan berikut ini ke file build.gradle Anda di dalam defaultConfigpenutupan, tepat setelah versionNamebaris:ndk { moduleName="hello-world" }

  4. Di maindirektori modul aplikasi Anda , buat folder baru bernama jni.

  5. Di folder itu, buat file bernama hello-world.c, yang akan Anda lihat di bawah.

  6. Lihat contoh Activitykode di bawah ini untuk contoh bagaimana memanggil metode (atau itu fungsi?) Di 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'])
}

Temukan kode sumber lengkap dari aplikasi yang sangat mirip di sini (minus NDK).


Saya melakukan persis seperti yang diperintahkan dalam proyek saya saat ini, tetapi hal-hal NDK masih belum bisa dibangun. Ada ide? Sepertinya itu membangun segalanya, tapi hanya melewatkan barang-barang jni.
alice.harrison

@NannuoLei terima kasih, saya mencoba tetapi saya mendapatkan masalah di mana .so tidak dihasilkan. Segala sesuatu yang lain tampaknya berfungsi, tetapi ketika saya menjalankan apkg di emulator, ia mengeluh tidak dapat memuat objek yang dibagikan.
aaa90210

@ aaa90210 apakah emulator Anda didasarkan pada gambar x86? Secara default NDK hanya akan menghasilkan pustaka ARMEABI, jika Anda ingin membangun gambar x86 Anda dapat menambahkan baris ini ke Application.mk: APP_ABI: = armeabi x86
Leo mendukung Monica Cellio

1
itu berhasil dengan saya. PS: siapa pun yang melihat jawaban ini, jangan lupa ganti Java_me_mattlogan_ndktest_MainActivity_stringFromJNIke milik Anda sendiri :)
AbdulMomen عبدالمؤمن

8

Jika Anda berada di unix versi terbaru (0.8) menambahkan ndk-build. Berikut cara menambahkannya:

android.ndk {
    moduleName "libraw"
}

Ia mengharapkan untuk menemukan JNI di bawah 'src / main / jni', jika tidak Anda dapat mendefinisikannya dengan:

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

Mulai 28 JAN 2014 dengan versi 0.8 build rusak di windows, Anda harus menonaktifkan build dengan:

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

1
Apakah ada dokumentasi untuk fitur itu? Saya tidak dapat menemukannya. Saat ini tampaknya sepenuhnya mengabaikan Android.mk/Application.mk saya.
plaisthos

Saya belum menemukan. Mungkin menyelinap ke dalam gedung setengah matang. Saya berada di windows jadi saya hanya dapat mengkonfirmasi bahwa ia gagal mencoba memanggil skrip unix ndk-build. Tidak ada alasan lain untuk memanggil itu untuk mengintegrasikan kompilasi asli dalam gradle. Apakah Anda di Unix?
Anthony


itu sebenarnya mengharapkan untuk menemukan file *. jadi prebuilt di jniLibs.srcDirs
Alpine

Saya tidak setuju berdasarkan fakta bahwa crash memanggil ndk-build yang sama sekali tidak perlu jika memerlukan perpustakaan yang dibangun. Saya tidak dapat mengkonfirmasi karena saya tidak punya waktu untuk vm Linux sekarang.
Anthony

7

Solusi yang elegan ditunjukkan di https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J .

Pada dasarnya Anda membuat toples yang berisi "lib / armeabi / yourlib.so" dan kemudian memasukkan toples ke dalam build.


Ya. Itu hanya berfungsi dengan baik jika Anda tidak sering mengubah kode asli Anda. Dan Anda harus memasukkan file jar biner dalam repositori. Kalau tidak, Anda akan berakhir dengan skrip build yang membuat toples on the fly.
plaisthos

1
Saya telah memodifikasi contoh Hello-JNI Android dengan skrip bash sederhana yang membungkus ndk-build, menghasilkan .jars untuk masing-masing .sodan menempatkannya di jalur build gradle untuk mengurangi rasa sakit ini. Saksikan berikut ini.
dbro

4

Jawaban yang bagus mengotomatiskan pengemasan .sofile-file yang siap dikompilasi diberikan dalam utas lain (tertutup) . Untuk membuatnya bekerja, saya harus mengubah jalur:

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

ke:

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

Tanpa perubahan ini, .sofile tidak ditemukan, dan tugas untuk mengemasnya tidak akan pernah berjalan.


Pembaruan: harap dicatat bahwa di Studio Android yang lebih baru (setidaknya dalam 1,5) kode asli lebih baik dimasukkan, dan tidak perlu melakukan tugas terpisah ini untuk mengemas kode Anda.
HYS

4

Jawaban dari @plaisthos pecah di versi gradle terbaru, tetapi masih ada cara untuk melakukannya. Buat native-libsdirektori di root direktori proyek Anda dan salin semua lib kami ke direktori ini.

Tambahkan baris berikut ke build.gradle Anda. Bangun dan bahagia.

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

Ini adalah kode yang saya gunakan untuk membangun menggunakan android-ndk dari gradle. Untuk ini tambahkan jalur direktori ndk di gradle.propertiesmis. menambahkan ndkdir=/home/user/android-ndk-r9ddan menempatkan semua file JNI dalam folder nativedi src/main/seperti yang Anda lihat dari kode diposting di bawah ini. Ini akan membuat jar dengan lib asli yang dapat Anda gunakan secara normal seperti padaSystem.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

Saya telah menggunakan kode berikut untuk mengkompilasi pustaka dropbox asli, saya menggunakan Android Studio 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)
}


1

Untuk memperluas apa yang dikatakan Naxos (Terima kasih Naxos karena mengirim saya ke arah yang benar!), Saya belajar sedikit dari contoh NDK yang baru dirilis dan memposting jawaban dalam pertanyaan serupa di sini.

Cara mengkonfigurasi NDK dengan plugin Android Gradle 0.7

Posting ini memiliki detail lengkap tentang menautkan pustaka asli prebuilt ke aplikasi Anda untuk berbagai arsitektur serta informasi tentang cara menambahkan dukungan NDK langsung ke skrip build.gradle. Untuk sebagian besar, Anda tidak perlu melakukan pekerjaan di sekitar zip dan salin lagi.


1

Berikut adalah langkah-langkah yang saya gunakan untuk membuat NDK bekerja di proyek Android Studio saya. Saya menggunakan tutorial ini untuk membantu saya https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

Untuk menggunakan NDK, Anda harus menambahkan baris NDK ke local.properties. Jadi di bawah sdk.dir Anda tambahkan

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

Di aplikasi saya build.gradle saya memiliki kode berikut

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

moduleName adalah nama yang ingin Anda berikan kode asli Anda. Saya percaya inilah yang akan disebut perpustakaan bersama. ldLibs memungkinkan saya untuk masuk ke LogCat, stl adalah stl yang ingin Anda impor. Ada banyak opsi, sama seperti Eclipse NDK. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cFlags masih merupakan sihir hitam bagi saya. Saya belum menemukan sumber yang bagus untuk semua opsi dan apa yang mereka berikan kepada saya. Cari di sekitar StackOverflow untuk apa pun yang Anda butuhkan, di situlah saya menemukannya. Saya tahu bahwa c ++ 11 memungkinkan saya untuk menggunakan standar c ++ 11 yang baru.

Berikut adalah contoh bagaimana saya masuk ke LogCat dari kode asli

__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

konfigurasikan proyek di studio android dari eclipse: Anda harus mengimpor proyek eclipse ndk ke studio android tanpa mengekspor ke gradle dan berfungsi, Anda juga perlu menambahkan jalur ndk di local.properties , jika ada kesalahan, tambahkan

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

dalam file build.gradle kemudian buat folder jni dan file menggunakan terminal dan jalankan itu akan bekerja


1
Lihat lihat jawaban saya sendiri. Itulah solusi yang saat ini saya gunakan tetapi itu bukan solusi.
plaisthos

1

Sekarang Android Studio berada di saluran stabil, cukup mudah untuk menjalankan sampel android-ndk . Sampel ini menggunakan plugin eksperimental ndk dan lebih baru daripada yang ditautkan dari dokumentasi online Android NDK. Setelah Anda tahu mereka berfungsi, Anda dapat mempelajari file build.gradle, local.properties, dan gradle-wrapper.properties dan memodifikasi proyek Anda sesuai dengan itu. Berikut ini adalah langkah-langkah untuk membuatnya bekerja.

  1. Buka pengaturan, Penampilan & Perilaku, Pengaturan Sistem, Android SDK, pilih tab SDK Tools, dan periksa Android NDK versi 1.0.0 di bagian bawah daftar. Ini akan mengunduh NDK.

  2. Arahkan ke lokasi NDK yang baru diunduh. Perhatikan bahwa itu akan ditempatkan di direktori sdk / ndk-bundle. Lakukan ini dengan memilih File, Struktur Proyek, Lokasi SDK (di sebelah kiri), dan menyediakan jalur di bawah lokasi Android NDK. Ini akan menambahkan entri ndk ke local.properties mirip dengan ini:

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

Saya telah berhasil membangun dan menggunakan semua proyek dalam repositori dengan cara ini, kecuali gles3gni, native-codec dan builder. Saya menggunakan yang berikut ini:

Android Studio 1.3 build AI-141.2117773
sampel android-ndk yang diterbitkan 28 Juli 2015 (tautan di atas)
SDK Tools 24.3.3
NDK r10e diekstraksi ke C: \ Android \ sdk \ ndk-bundle
Plugin Gradle 2.5
Gradle 0.2.0
Windows 8.1 64 bit


1

NDK Build dan gradle (dasar)

Secara umum membangun dengan NDK adalah sesederhana dengan benar menentukan jalur ndkBuild ke Android.mk atau cmake path ke CMakeLists.txt. Saya merekomendasikan CMake pada Android.mk yang lebih lama karena dukungan Android Studio C / C ++ didasarkan pada CLion dan menggunakan CMake sebagai format proyeknya. Ini dalam pengalaman saya cenderung membuat IDE lebih responsif pada proyek yang lebih besar. Semua yang dikompilasi dalam proyek Anda akan dibangun dan disalin ke APK secara otomatis.

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

Menambahkan perpustakaan prebuilt ke proyek (lanjutan)

Pustaka statis (.a) di build NDK Anda akan secara otomatis disertakan, tetapi pustaka dinamis prebuilt (.so) perlu ditempatkan jniLibs. Ini dapat dikonfigurasi menggunakan sourceSets, tetapi Anda harus mengadopsi standar. Anda TIDAK PERLU perintah tambahan apa pun build.gradlesaat menyertakan pustaka prebuilt.

Tata letak jniLibs

Anda dapat menemukan informasi lebih lanjut tentang struktur di Panduan Pengguna Plugin Android Gradle .

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

Anda kemudian dapat memvalidasi APK yang dihasilkan berisi file .so Anda, biasanya di bawah build/outputs/apk/, gunakan unzip -l myApp.apkuntuk membuat daftar konten.

Membangun perpustakaan bersama

Jika Anda sedang membangun perpustakaan bersama di NDK Anda tidak perlu melakukan apa pun lebih lanjut. Ini akan dibundel dengan benar di APK.


0

Cukup tambahkan baris ini ke aplikasi 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)
}

Saya pikir pendekatan jniLibs.srcDirs lebih bersih daripada ini karena Anda dapat menggunakan abiFilter / rasa tetapi pendekatan Anda juga harus bekerja.
plaisthos

0

sekarang. Saya dapat memuat begitu sukses!

1. Tambahkan file .so ke jalur ini

Project:

| --src | - | --main | - | - | --java | - | - | --jniLibs | - | - | --armeabi | - | - | - | - | -. jadi file

2. tambahkan kode ini ke gradle.build

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

}

3.System.loadLibrary("yousoname");

  1. selamat tinggal untuk Anda, itu baik-baik saja dengan gradle 1.2.3

0
  1. Jika proyek Anda diekspor dari eclipse, tambahkan kode di bawah ini dalam file gradle :

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

2.Jika Anda membuat proyek di Android studio:

buat folder bernama jniLibs di src / main / , dan letakkan file * .so Anda di folder jniLibs.

Dan salin kode seperti di bawah ini dalam file gradle Anda :

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

0

Walaupun saya percaya SJoshi (oracle guy) memiliki jawaban paling lengkap, proyek SWIG adalah kasus khusus, menarik dan bermanfaat, pada saat itu, tetapi tidak digeneralisasi untuk sebagian besar proyek yang telah berhasil dengan baik dengan proyek standar semut SDK + NDK. Kita semua ingin menggunakan studio Android sekarang kemungkinan besar, atau menginginkan toolchain build CI yang lebih ramah untuk seluler, yang secara gradual menawarkan.

Saya telah memposting pendekatan saya, dipinjam dari suatu tempat (saya menemukan ini di SO, tetapi memposting inti untuk build.gradle aplikasi: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). Singkatnya, saya merekomendasikan yang berikut ini:

  • Jangan perbarui proyek Anda ke bangunan gradle terbaru
  • Gunakan com.android.tools.build:gradle:1.5.0 di root Proyek Anda
  • Gunakan com.android.aplikasi dalam proyek aplikasi Anda
  • Pastikan gradle.properties memiliki: android.useDeprecatedNdk = true (seandainya komplain)
  • Gunakan pendekatan di atas untuk memastikan bahwa jam dan jam usaha Anda membuat file Android.mk tidak akan dibuang. Anda mengontrol target lengkung mana yang akan dibangun. Dan instruksi ini baik untuk pengguna Windows, yang secara teoritis harus dapat membangun di windows tanpa masalah khusus.

Gradle untuk Android telah mengacaukan pendapat saya, sama seperti saya suka konsep pakar pinjaman dan struktur direktori untuk proyek. Fitur NDK ini telah "segera hadir" selama hampir 3+ tahun.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.