Студія Android, gradle та NDK


153

Я дуже новачок у всій цій програмі та підтримці Android Studio. Мені вдалося перетворити мій проект Android на gradle за допомогою опції експорту.

Але я шукаю деяку документацію або початковий момент, як інтегрувати збірку NDK в процес збирання gradle.

Якщо можливо, мені також потрібен якийсь етап "після", який копіює бінарні файли збірки (.so файли) в каталог активів.


Я опублікував свою відповідь у нижчезазначеному
Ахмад Алі Насір

24
Нові читачі. Будьте в курсі, що це питання було спочатку задано під час бета-версії Android Studio; відповідь з часом змінилася. Зверніть увагу на версію Gradle, згадану у відповідях, а також на те, коли відповіді були фактично розміщені.
Шон Біч

Якщо щось дійсно зміниться, я відредагую питання про відкликання статусу
plaisthos

Android Studio 1.3 на каналі канарів повністю підтримує NDK. Довідка: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 червня 2015 року: Android Studio 1.3 Beta тепер доступний у бета-каналі! На жаль, ця збірка ще не містить підтримки 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
Було б чудово, якби я міг використовувати NDK та завершення команд при налагодженні під Android Studio (та підтримкою Gradle)
powder366

1
@GREnvoy - Як налаштувати правильний конструктор NDK в студії Android? Чи можете ви PLZ дати мені кроки? :)
Шраван

7
@DirtyBeach Чому вона застаріла? Досі немає інтеграції NDK в Studio. Ми працюємо над цим, але зараз немає ЗНО.
Ксав'є Дюкрохет

2
Моя дія базувалася на тому, як я визначав "інтеграцію". Я зрозумів, що це означає "спосіб використання NDK з gradle", який зараз існує, хоча жоден з них не є фантастичним рішенням. Однак, виходячи з вашого коментаря, здається, ваша команда має на увазі щось інше, якою може бути справжня інтеграція. Я відкликаю своє попереднє твердження.
Шон Біч

2
Інтеграція NDK була оголошена під час Google IO 2015. Вона доступна в Android Studio 1.3 (попередній перегляд можна буде завантажити незабаром. Я опублікую посилання, коли воно буде доступне).
Cypress Frankenfeld

43

ОНОВЛЕННЯ: Android Studio із підтримкою NDK вже вийшов: http://tools.android.com/tech-docs/android-ndk-preview

Для побудови зі скриптом рішення Gradle, що знаходиться нижче, має працювати:

Я використовую свій сценарій збірки і додаю до свого файлу (здається, що працює для 0.8+): Це, здається, еквівалентно рішенню нижче (але приємніше виглядає у файлі gradle):

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

На жаль, збірка не виходить з ладу, якщо каталог не присутній або не містить .soфайлів.


5
З новою версією Android Studio це не працює?
порошок366

@ powder366 Дивіться мою відповідь.
Леандрос

2
Трохи магії Groovy: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Дякую, хлопці, за допомогу!
trnl

Яка процедура для Android Studio 0.8.9
Pandiri Deepak

1
@plaisthos Дякую за вказівку правильного напрямку! Другий рядок у сценарії gradle jni.srcDirs = [] //disable automatic ndk-buildдуже важливий, оскільки заважатиме Android Studio відновлювати вихідний код C / C ++. Я намагаюся розібратися в цьому два дні, поки не побачив вашу посаду, і це вирішило мою проблему. Я дійсно думаю, що збір NDK краще окремо будувати лише за допомогою makefile командного рядка Android.mk, а не за сценарієм gradle, оскільки C / C ++ будується Makefile вже понад 40 років!
тонга

40

З оновленням Android Studio до 1.0 підтримка ланцюжків інструментів NDK надзвичайно покращилася ( зверніть увагу: будь ласка, прочитайте мої оновлення внизу цієї публікації, щоб побачити використання нового експериментального плагіна Gradle та Android Studio 1.5 ).

Android Studio та NDK інтегровані досить добре, так що вам просто потрібно створити блок ndk {} у своєму build.gradle модуля та встановити вихідні файли у каталог (module) / src / main / jni - і ви зроблено!

Більше немає ndk-build з командного рядка.

Про це я написав у своєму блозі тут: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

Важливі точки:

Тут потрібно знати дві речі. За замовчуванням, якщо у вас є зовнішні бібліотеки, які ви хочете завантажити в додаток Android, їх шукають у (модулі) / src / main / jniLibs за замовчуванням. Ви можете змінити це за допомогою установки sourceSets.main.jniLibs.srcDirs у build.gradle модуля. Вам знадобиться підкаталог з бібліотеками для кожної архітектури, на яку ви орієнтуєтеся (наприклад, x86, arm, mips, arm64-v8a тощо).

Код, який ви хочете скласти за замовчуванням за допомогою інструментальної мережі NDK, буде розташований у (модулі) / src / main / jni і аналогічно вище, ви можете змінити його, встановивши sourceSets.main.jni.srcDirs у build.gradle вашого модуля

і помістіть це в 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 року

Коли Android Studio 1.3 вийде, має бути краща підтримка C ++ через плагін JetBrains CLion. На даний момент я припускаю, що це дозволить розробляти Java та C ++ з Android Studio; однак я думаю, що нам ще потрібно буде використовувати розділ Gradle NDK, як я вже говорив вище. Крім того, я думаю, все ще буде необхідність писати Java <-> C ++ файли обгортки, якщо CLion не виконає їх автоматично.

ОНОВЛЕННЯ: 5 січня 2016 року

Я оновив свій блог та Github repo (у галузі розвитку) для використання Android Studio 1.5 з останнім експериментальним плагіном Gradle (0.6.0-alpha3).

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

Збірка Gradle для розділу 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
}

Крім того, Android Studio має автоматичне доповнення для C ++ - обгортки, згенерованої Java, використовуючи "рідне" ключове слово:

Приклад автоматичного завершення C ++ - обгортки Java

Однак це не зовсім райдужно ... Якщо ви використовуєте SWIG, щоб обернути бібліотеку для автоматичного генерування коду, а потім спробуйте використати нативне ключове слово автогенерування, він поставить код у неправильне місце у вашому Swig _wrap .cxx файл ... Отже, вам потрібно перемістити його в блок "зовнішній С":

C ++ - обгортка Java переміщена в потрібне місце

ОНОВЛЕННЯ: 15 жовтня 2017 року

Буду звільнений, якби я не згадував, що Android Studio 2.2 по суті має «рідну» (без каламбуру) підтримку ланцюжка інструментів NDK через Gradle та CMake. Тепер, коли ви створюєте новий проект, просто виберіть підтримку C ++, і ви готові йти.

Вам все одно потрібно буде генерувати власний код шару JNI або використовувати техніку SWIG, про яку я згадував вище, але ліси C ++ в проекті Android зараз тривіальні.

Зміни у файлі CMakeLists (саме там ви розміщуєте свої вихідні файли C ++) буде обрано програмою Android Studio, і він автоматично повторно складе будь-які пов’язані бібліотеки.


1
покласти * .so в (модуль) / src / main / jniLibs
fawkes

чому NDEBUG завжди встановлюється під час використання Android Studio, навіть у налагодженнях налагодження
pt123

35

У Google IO 2015 компанія Google оголосила про повну інтеграцію NDK в Android Studio 1.3.

Зараз він не переглядається та доступний для всіх: https://developer.android.com/studio/projects/add-native-code.html

Стара відповідь: Gradle автоматично телефонує, ndk-buildякщо jniу джерелах проекту є каталог.

Це працює на Android студії 0.5.9 (збірка канарок).

  1. Завантажте NDK

  2. Або додайте ANDROID_NDK_HOMEдо змінних оточення або додайте ndk.dir=/path/to/ndkдо своїх local.propertiesу проекті Android Studio. Це дозволяє Android-студії автоматично запускати ndk.

  3. Завантажте останні зразки проектів gradle, щоб побачити приклад ndk-проекту. (Вони знаходяться внизу сторінки). Хороший зразок проекту ndkJniLib.

  4. Скопіюйте gradle.buildпроекти з зразків NDK. Це буде виглядати приблизно так. Це 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. Як вирішення, ви можете сказати gradle, щоб відключити atuomatic ndk-build виклик, а потім вказати каталог джерел ndk вручну.

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 у своєму сценарії збірки gradle, оскільки ви просто відключили автоматичний виклик.

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

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

Так. Але це працює лише на платформах Unix, а також обмежено, якщо ви складніші, ніж дуже проста конфігурація / makefi-файли ndk.
plaisthos

Так, він автоматично створить файли для обмежених речей, які ви можете встановити у файлі збірки gradle, однак є рішення. Я додав це до своєї відповіді.
Cypress Frankenfeld

1
Виклик ndk-build працюватиме лише в командному рядку не з Android Studio.
Камерон Лоуелл Палмер

Хоча це не сама остання відповідь, вона, мабуть, є найбільш точною. Зверніть особливу увагу на крок 3: "Завантажте останні проекти зразків градусів".
Шон Біч

4
Я використовую цей хак замість відключення src dir, щоб я міг редагувати файли c / c ++ в межах idetasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
sherpya

23

Я знайшов "gradle 1,11 com.android.tools.build:gradleasures.9.+" підтримує попереднє збирання ndk зараз, ви можете просто поставити * .so в dir src / main / jniLibs. при складанні gradle буде пакувати ndk в потрібне місце.

ось мій проект

Проект:
| --src
| - | --основна
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | -. файли
| --ліб
| - | - інше.jar

18

Як сказав Ксав'є, ви можете розмістити свої попередні програми в / src / main / jniLibs /, якщо ви використовуєте gradle 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) це досить просто. Ось такі кроки для створення додатка типу "Hello world":

  1. Завантажте Android NDK і покладіть кореневу папку кудись здоровим - можливо, в те саме місце, де і папка SDK.

  2. Додайте у local.propertiesфайл наступне : ndk.dir=<path-to-ndk>

  3. Додайте до файлу build.gradle всередині defaultConfigзакриття, відразу після 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).


Я роблю точно так, як прописано в моєму поточному проекті, але все ще не будується. Будь-які ідеї? Здається, він будує все інше, але просто пропускає речі jni.
alice.harrison

@NannuoLei дякую, я спробував, але у мене виникає проблема, коли .so не створюється. Все інше, здається, працює, але коли я запускаю apkg в емуляторі, він скаржиться, що не може завантажити спільний об'єкт.
aaa90210

@ aaa90210 ваш емулятор на основі зображення x86? За замовчуванням NDK просто створить бібліотеку ARMEABI, якщо ви хочете створити образ x86, ви можете додати цей рядок у Application.mk: APP_ABI: = armeabi x86
Лео підтримує Моніку Челіо

1
воно працювало зі мною. PS: хто бачить цю відповідь, не забудьте змінити Java_me_mattlogan_ndktest_MainActivity_stringFromJNIсвою власну :)
AbdulMomen عبدالمؤمن

8

Якщо ви перебуваєте на unix, остання версія (0.8) додає ndk-build. Ось як його додати:

android.ndk {
    moduleName "libraw"
}

Він розраховує знайти JNI під 'src / main / jni', інакше ви можете визначити це за допомогою:

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

Станом на 28 січня 2014 року з версією 0.8 збірка зламана на windows, вимкніть збірку за допомогою:

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

1
Чи є документація на цю функцію? Я не міг знайти жодного. На даний момент, здається, повністю ігнорую мій Android.mk/Application.mk.
плейстос

Я не знайшов жодного. Можливо, він увірвався в збірну напівфабрикат. Я в Windows, тому можу лише підтвердити, що це не вдається при спробі викликати unix ndk-build скрипт. Не було б ніякої іншої причини закликати це потім інтегрувати натисну компіляцію в gradle. Ви в Unix?
Ентоні


він фактично розраховує знайти попередньо вбудовані файли * .so у jniLibs.srcDirs
Альпійський

Я не погоджуюся, виходячи з того, що він виходить з ладу ndk-build, що абсолютно не потрібно, якщо для цього потрібні вбудовані бібліотеки. Я не можу підтвердити, оскільки зараз не маю часу на vm Linux.
Ентоні

7

Елегантне вирішення показано на https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J .

В основному ви створюєте банку, яка містить "lib / armeabi / yourlib.so", а потім включаєте банку в збірку.


Так. Це добре працює лише в тому випадку, якщо ви часто не змінюєте натурний код. І вам доведеться включати бінарні файли jar у сховище. В іншому випадку ви закінчите сценарій складання, який створює банку на льоту.
plaisthos

1
Я змінив приклад Hello-JNI Android на простому скрипті bash, який обгортає ndk-build, генерує .jars для кожного .soі розміщує їх у шляху побудови gradle, щоб полегшити цю біль. Перевір.
дбро

4

Хороша відповідь щодо автоматизації упаковки легко складених .soфайлів наведена в іншій (закритій) темі . Щоб працювати так, мені довелося змінити лінію:

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

в:

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

Без цієї зміни .soфайли не були знайдені, і тому завдання щодо їх упаковки ніколи не виконується.


Оновлення: зауважте, що в нових Android Studios (принаймні в 1,5) рідний код набагато краще включений, і не потрібно робити це окреме завдання для упаковки вашого коду.
HYS

4

Відповідь від @plaisthos виникла в останній версії gradle, але все ще є спосіб це зробити. Створіть 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і поставити все JNI файли в папці nativeв , 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

Я використовував наступний код для складання власних бібліотек випуску, я використовую 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

Щоб розширити те, що сказав Naxos (Спасибі Naxos за те, що він направив мене в правильному напрямку!), Я дізнався зовсім небагато з нещодавно опублікованих прикладів NDK і розмістив відповідь у подібному питанні тут.

Як налаштувати NDK за допомогою плагіна Android Gradle 0.7

У цій публікації є повна інформація про підключення попередньо вбудованих власних бібліотек у ваш додаток для різних архітектур, а також інформація про те, як додати підтримку NDK безпосередньо до сценарію build.gradle. Здебільшого вам більше не потрібно займатись роботою навколо zip та копіювання.


1

Ось кроки, якими я користувався, щоб NDK працював у проекті Android Studio. Цей підручник я використав, щоб допомогти мені https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

Для використання NDK потрібно додати рядок NDK до local.properties. Тож під ваш sdk.dir додайте

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

У своїх додатках build.gradle у мене є такий код

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

moduleName - ім'я, якому ви хочете дати свій рідний код. Я вірю, що саме так називатиметься спільна бібліотека. ldLibs дозволяє мені увійти до LogCat, stl - це stl, який потрібно імпортувати. Варіантів дуже багато, як і у Eclipse NDK. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cFlags - це все ще певна кількість чорної магії для мене. Я не знайшов хорошого джерела для всіх варіантів і того, що вони мені дають. Шукайте навколо StackOverflow все необхідне, саме там я його знайшов. Я знаю, що c ++ 11 дозволяє мені використовувати новий стандарт c ++ 11.

Ось приклад того, як я входжу в LogCat з власного коду

__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

конфігуруйте проект в андроїд-студії від eclipse: вам потрібно імпортувати eclipse ndk-проект до андроїд-студії без експорту до gradle, і він працює, також вам потрібно додати шлях до ndk у local.properties , якщо показує помилку, то додати

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

у файлі build.gradle тоді створіть папку jni та файл за допомогою терміналу та запустіть його


1
Дивіться див. Мою власну відповідь. Це рішення, яке я зараз використовую, але це насправді не рішення.
plaisthos

1

Тепер, коли Android Studio знаходиться в стабільному каналі, досить просто запустити зразки андроїд-ndk . Ці зразки використовують експериментальний плагін ndk і новіші, ніж ті, які пов’язані з онлайн-документацією на Android NDK. Коли ви дізнаєтесь, що вони працюють, ви можете вивчити файли build.gradle, local.properties та gradle-wrapper.properties та змінити ваш проект відповідно. Нижче наведено кроки, щоб змусити їх працювати.

  1. Перейдіть до налаштувань, зовнішнього вигляду та поведінки, системних налаштувань, Android SDK, виберіть вкладку «Інструменти SDK» та перевірте Android NDK версії 1.0.0 внизу списку. Це завантажить NDK.

  2. Вкажіть місце щойно завантаженого NDK. Зауважте, що він буде розміщений у каталозі sdk / ndk-bundle. Зробіть це, вибравши «Файл», «Структура проекту», «Місце розташування SDK» (зліва) та надайте шлях під розташуванням Android NDK. Це додасть запис ndk до local.properties, подібному до цього:

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

Я успішно будував і розгортав усі проекти в сховищі таким чином, крім gles3gni, native-codec та builder. Я використовую наступне:

Android Studio 1.3 build AI-141.2117773
андроїд-ndk зразки опубліковано 28 липня 2015 (посилання вище)
SDK Tools 24.3.3
NDK r10e витягнуто на C: \ Android \ sdk \ ndk-bundle
Gradle 2.5
Gradle плагін 0.2.0
Windows 8.1 64 біт


1

NDK Побудови та студії (базові)

Як правило, побудувати за допомогою NDK так само просто, як правильно вказати шлях ndkBuild до Android.mk або шлях cmake до CMakeLists.txt. Я рекомендую CMake для старих Android.mk, оскільки підтримка C / C ++ для Android Studio базується на CLion, і він використовує CMake в якості свого формату проекту. Це, на мій досвід, прагнуло зробити IDE більш чутливим до більш великих проектів. Все, що складено у вашому проекті, буде створено та скопійовано в APK автоматично.

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

Додавання до проекту попередньо вбудованих бібліотек (розширено)

Статичні бібліотеки (.a) у вашій збірці NDK будуть автоматично включені, але попередньо вбудовані динамічні бібліотеки (.so) потрібно буде розмістити jniLibs. Це можна налаштувати за допомогою sourceSets, але вам слід прийняти стандарт. Вам НЕ ПОТРІБНІ додаткові команди, build.gradleвключаючи попередньо створені бібліотеки.

Макет jniLibs

Додаткову інформацію про структуру можна знайти в Посібнику користувача Android Gradle Plugin .

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

Ви можете перевірити отриманий APK містить ваші файли .so, як правило , під build/outputs/apk/, використовуючи unzip -l myApp.apkсписок вмісту.

Створення спільних бібліотек

Якщо ви будуєте спільну бібліотеку в NDK, вам більше нічого не потрібно робити. Він буде правильно вбудований в APK.


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 / аромати, але ваш підхід також повинен працювати.
plaisthos

0

Тепер я можу завантажити такий успіх!

1.Додайте файл .so до цього шляху

Project:

| --src | - | --основна | - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - | - | - | -. так файли

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. goodluck для вас, це нормально з gradle 1.2.3

0
  1. Якщо ваш проект експортується із затемнення, додайте коди нижче у файл gradle:

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

2.Якщо ви створюєте проект у студії Android:

створіть папку з назвою jniLibs у src / main / , та помістіть свої * .so файли у папку jniLibs.

І скопіюйте код, як показано нижче, у свій файл gradle:

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

0

Хоча я вважаю, що SJoshi (хлопець з оракула) має найбільш повну відповідь, проект SWIG - це особливий випадок, цікавий і корисний, при цьому, але не узагальнений для більшості проектів, які добре справились зі стандартними проектами на основі муніципальних SDK + NDK. Ми всі хотіли б скористатися Android-студією зараз, швидше за все, або хочемо більш зручного для СІ побудови інструментів для мобільних пристроїв, який теоретично пропонує gradle.

Я розмістив свій підхід, запозичений десь (я знайшов це на SO, але опублікував суть для програми build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). Якщо коротко, то рекомендую наступне:

  • Не оновлюйте проект до останньої збірки gradle
  • Використовуйте com.android.tools.build:gradle:1.5.0 в корені проекту
  • Використовуйте com.android.application у своєму проекті проекту
  • Переконайтесь, що gradle.properties має: android.useDeprecatedNdk = true (на випадок, коли він скаржиться)
  • Використовуйте вищезазначений підхід, щоб гарантувати, що ваші години та години на створення файлів Android.mk не будуть відкинуті. Ви керуєте, які цілі (арки) будувати. І ці вказівки люблять користувачів Windows, які теоретично повинні мати можливість створювати на Windows без особливих проблем.

На мій погляд, Gradle для Android був безлад, так само, як мені подобаються запозичені поняття Maven та надійна структура каталогів для проекту. Ця функція NDK "скоро з'являється" протягом майже 3+ років.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.