Android ndk location android studio

Install and configure the NDK and CMake

To compile and debug native code for your app, you need the following components:

  • The Android Native Development Kit (NDK): a set of tools that allows you to use C and C++ code with Android.
  • CMake: an external build tool that works alongside Gradle to build your native library. You do not need this component if you only plan to use ndk-build.
  • LLDB: the debugger Android Studio uses to debug native code. By default, LLDB will be installed alongside Android Studio.

This page describes how to install these components automatically, or by using Android Studio or the sdkmanager tool to download and install them manually.

Install NDK and CMake automatically

Android Gradle Plugin 4.2.0+ can automatically install the required NDK and CMake the first time you build your project if their licenses have been accepted in advance. If you’ve already read and agree to the license terms, then you can pre-accept the licenses in scripts with the following command:

Install the NDK and CMake

When you install the NDK, Android Studio selects the latest available NDK. For most projects, installing this default version of the NDK is sufficient. If your project needs one or more specific versions of the NDK, though, you can download and configure specific versions. Doing so helps you ensure reproducible builds across projects that each depend on a specific version of the NDK. Android Studio installs all versions of the NDK in the android-sdk /ndk/ directory.

To install CMake and the default NDK in Android Studio, do the following:

With a project open, click Tools > SDK Manager.

Click the SDK Tools tab.

Select the NDK (Side by side) and CMake checkboxes.

Figure 1: The SDK Tools window showing the NDK (Side by side) option

Click OK.

A dialog box tells you how much space the NDK package consumes on disk.

Click OK.

When the installation is complete, click Finish.

Your project automatically syncs the build file and performs a build. Resolve any errors that occur.

Configure a specific version of CMake

The SDK Manager includes the 3.6.0 forked version of CMake and version 3.10.2. Projects that don’t set a specific CMake version are built with CMake 3.10.2. To set the CMake version, add the following to your module’s build.gradle file:

Groovy

Kotlin

If you want to use a CMake version that is not included by the SDK Manager, follow these steps:

  1. Download and install CMake from the official CMake website.
  2. Specify the CMake version you want Gradle to use in your module’s build.gradle file.

Either add the path to the CMake installation to your PATH environment variable or include it in your project’s local.properties file, as shown. If Gradle is unable to find the version of CMake you specified in your build.gradle file, you get a build error.

If you don’t already have the Ninja build system installed on your workstation, go to the official Ninja website, and download and install the latest version of Ninja available for your OS. Make sure to also add the path to the Ninja installation to your PATH environment variable.

Install a specific version of the NDK

To install a specific version of the NDK, do the following:

With a project open, click Tools > SDK Manager.

Click the SDK Tools tab.

Select the Show Package Details checkbox.

Select the NDK (Side by side) checkbox and the checkboxes below it that correspond to the NDK versions you want to install. Android Studio installs all versions of the NDK in the android-sdk /ndk/ directory.

Figure 2: The SDK Tools window showing the NDK (Side by side) options

Click OK.

A dialog box tells you how much space the NDK package(s) consumes.

Click OK.

When the installation is complete, click Finish.

Your project automatically syncs the build file and performs a build. Resolve any errors that occur.

Configure each module with the version of the NDK you want it to use. When using Android Studio 3.6 or higher, if you do not specify the version, the Android Gradle plugin chooses a version that it is known to be compatible with.

Configure specific versions of the NDK in your project

You may need to configure the version of the NDK in your project if one of the following is true:

    Your project is inherited and you need to use specific versions of the NDK and the Android Gradle plugin (AGP). For more information, see Configure the NDK for the Android Gradle plugin.

You have multiple versions of the NDK installed and you want to use a specific one. In this case, specify the version using the android.ndkVersion property in the module’s build.gradle file, as shown in the following code sample.

Groovy

Kotlin

Default NDK version per AGP version

Before release, each AGP version is thoroughly tested with the latest stable NDK release at that time. For AGP version 3.6 and above, that NDK version will be used to build your projects if you do NOT specify an NDK version in the build.gradle file. The default NDK version is documented inside the AGP release notes. The current default NDK versions are listed in the following table:

Android Studio/Gradle Plugin Version
7.0 4.2 4.1 4.0 3.6 3.5 3.4
Default NDK version
specified for the version of AGP
21.4.7075529 21.4.7075529 21.1.6352462 21.0.6113669 20.0.5594570 No default specified

Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.

Источник

Использование NDK в Android Studio

В настоящее время среди Android-девелоперов большую популярность имеет среда разработки Android Studio, основанная на IntelliJ IDEA от JetBrains. Однако, при использовании данной IDE, могут возникнуть проблемы при разработке приложений, использующих нативный код, так как Android NDK рассчитан преимущественно на использование IDE Eclipse и ADT.

Цель данной статьи — подробное описание процесса создания Android-приложения, использующего NDK в Android Studio, в частности — предложение достаточно простой и эффективной конфигурации gradle (системы сборки пакетов, используемая в Android Studio), гарантирующей включение нативных библиотек в APK-файл. Также статья включает краткую инструкцию работы с NDK в IDE Eclipse и введение в нативную разработку, достаточное для написания первого приложения.

Данная статья предназначена преимущественно для начинающих разработчиков. Описанное решение не является единственным, но оно достаточно удобно, особенно для тех, кто работал с NDK в Eclipse. Если кому-то из читателей объяснение покажется слишком подробным, то в конце статьи есть краткое резюме, описывающее лишь алгоритм требуемых действий без комментариев к каждому шагу.

Так как существует множество статей, описывающих работу с NDK, я не буду использовать в качестве примера сложные библиотеки, а ограничусь лишь самым простым примером hello-jni. Исходный код данного примера можно найти в каталоге /samples/hello-jni

В среде Eclipse особых проблем с использованием NDK не возникало. Каталог проекта выглядит примерно так:

Рис.1 Главный каталог проекта для Eclipse

Нас интересуют каталоги jni и libs. Каталог jni содержит исходные коды на нативных языках (*.c; *.cpp), заголовочные файлы (*.h), makefiles (*.mk). Долго останавливаться на предназначении данных файлов не буду, так как этому посвящено немало материалов и статей. Упомяну лишь, что jni означает java native interface. Именно через этот интерфейс производится вызов нативных процедур из кода на java. Поэтому не забывайте подключать библиотеку в ваши c/c++ файлы и помните о правильном синтаксисе функций, которые будут вызываться через jni. Например, в моём случае приложение имеет package name:
evi.ntest
поэтому описание функции выглядит так:

где jstring — название типа данных c, соответствующего типу string в java, Java — в данном случае служебный префикс, показывающий язык, из которого будет вызвана функция, evi_ntest — имя пакета, который будет вызывать функцию, MainActivity — имя активити, из которой будет вызываться функция, stringFromJNI — название функции.
В java-коде описание данной функции выглядит гораздо проще:

Не забывайте также указывать используемые файлы кода в .mk файлах. Для начала можете воспользоваться .mk файлами из примеров NDK, модифицируя названия файлов, но в дальнейшем рекомендую изучить их структуру.

Каталог libs содержит готовые бинарные библиотеки для различных архитектур процессоров (по умолчанию — armeabi). Динамическая библиотека представляет собой файл с расширением .so, статическая — файл с расширением .a. Для получения данных библиотек требуется компиляция исходных кодов с помощью Android NDK. В Unix-системах (в моём случае — Mac OSX) для этого требуется в терминале ввести следующие строчки:

При этом NDK автоматически компилирует исходные коды из папки jni и помещает полученные библиотеки в libs/armeabi (также можно с помощью параметров командной строки задать компиляцию под x86, mips, arm v7-neon процессоры).
При использовании Windows потребуется воспользоваться дополнительными утилитами, возможно — плагинами для MS Visual Studio.
В любом случае, не имеет значения, каким именно способом получены готовые библиотеки, важен факт, что если в папке с проектом находится подкаталог libs, Eclipse при сборке автоматически включает его содержимое в APK-файл.

Так как данная статья посвящена лишь основам работы с NDK, то на этом введение в программирование на нативных языках под android я закончу. Для более подробного ознакомления с принципами нативной разработки рекомендую изучить примеры из каталога /samples/, а также читать статьи, в том числе и на русском языке. Пример хорошей статьи о Android NDK на русском языке, советую обратить внимание (написана не мной):

Перехожу к основному разделу статьи — настройке IDE Android Studio для работы с нативным кодом.

Среда Android Studio по умолчанию собирает APK с помощью gradle. Данный сборщик имеет широкие возможности кастомизации, но при стандартных настройках gradle не включает нативные библиотеки в APK-файл.

Рассмотрим частичную структуру проекта в Android Studio:

Рис.2 Путь к исходному коду проекта Android Studio.

При работе у меня возникло логичное желание разместить папку jni в каталоге src/main, так как именно там хранятся все остальные файлы с исходным кодом. Разумеется, читатель может размещать каталог jni там, где ему удобно. Главное — не забыть собрать бинарные библиотеки с помощью NDK (повторюсь, в UNIX системах для этого нужно в терминале перейти к каталогу, содержащему jni, затем вызвав исполняемый файл ndk-build, лежащий в папке с NDK, прописав полный путь к нему в этом же терминале, в MS Windows нужно использовать дополнительные утилиты). Проблема же заключается в том, что по умолчанию gradle не будет упаковывать в APK библиотеки.

Однако gradle несложно настроить на включение в сборку java-библиотек (файлов *.jar). Стоит заметить, что jar-файлы представляют собой zip-архивы, содержащие какие-либо ресурсы, а также объектный код. Таким образом, для включения бинарных библиотек *.so и *.a достаточно упаковать их в jar-файл.
Делается это так:

  • Переименовываем папку libs, содержащую наши бинарные библиотеки в lib
  • Сжимаем данную папку любым zip-архиватором
  • Меняем расширение полученного файла на .jar

Полученную библиотеку можно подключить на этапе сборки проекта, при этом полученный APK-файл будет включать двоичные библиотеки, а приложение — вызывать процедуры, написанные на нативном коде.
Данный вопрос не раз обсуждался на различных англоязычных форумах, например Stack Overflow:
stackoverflow.com/questions/16667903/android-studio-gradle-and-ndk
Однако, данная информация достаточно краткая, разрозненная и требует от читателя определённых знаний синтаксиса gradle. Цель моей статьи – предоставить читателям подробное русскоязычное объяснение, доступное даже тем, кто только начал работать с Android Studio и gradle.

Давайте рассмотрим 2 способа упаковки библиотек: ручной и автоматический.

Ручной способ упаковки:

Данный способ весьма неудобен, однако имеет место на существование. Допустимый случай применения на практике: наличие готовой библиотеки и отсутствие необходимости её изменять. В таком случае, описанные ниже операции потребуется выполнить лишь один раз.

Откройте build.gradle, находящийся по адресу » / Project/ /», в моём случае:

Рис.3 Местонахождение конфигурируемого файла build.gradle.

Данный файл изначально выглядит приблизительно так:

В самом низу есть раздел dependencies. Туда следует добавить такую строчку:

compile fileTree(dir: ‘src/main/’, include: ‘*.jar’)

Рассмотрим эту команду: gradle в ходе компиляции будет вынужден включить дерево файлов (структуру файлов и папок, соответствующих заданной маске ), расположенное по адресу ‘src/main/’ (т.е. в том каталоге, где расположены исходные коды, а также созданный нами jar файл), при этом в качестве маски использован параметр ‘*.jar’, т.е. включатся будут все файлы с таким расширением. Обратите внимание, что в данном случае путь считается относительно месторасположения файла build.gradle.
В результате выполнения данной команды gradle распакует jar-файл и включит двоичные библиотеки в APK-файл.

Ознакомтесь с модифицированным файлом build.gradle, что бы не перепутать dependencies и buildscript.dependencies.

Читатель скорее всего подметит, что данный способ весьма неудобен при наличии необходимости частых изменений в нативном коде, так как после каждой перекомпиляции необходимо удалять старый jar-файл, переименовывать папку libs в lib, архивировать её, менять расширение архива. Поэтому воспользуемся мощью gradle и автоматизируем процесс.

Сборщик пакетов gradle позволяет создавать задания (функции), также в его возможности входит создание различных типов архивов, в том числе zip. Воспользуемся этим и добавим в build.gradle (расположение данного файла рассмотрено выше) такие строчки:

Данный отрывок кода можно добавить в любую часть файла, кроме существующих разделов, например в конец файла. Я поместил их перед разделом dependencies.
Этот код включает в себя task, который создает в папке build, находящийся по адресу » / Project/ /» подкаталог native-libs, в этой подпапке создается файл native-libs.jar, структура файла соответствует требуемой структуре java-библиотеки, содержащей бинарные библиотеки .so. Если Вы планируете использовать также статические библиотеки .a, то вместо строки:

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

Вам следует использовать:

from fileTree(dir: ‘src/main/libs’, include: ‘**/*.*’)

Далее остается добавить в раздел dependencies строку:

compile fileTree(dir: «$buildDir/native-libs», include: ‘native-libs.jar’)

В ходе сборки эта команда включит содержимое созданной программно библиотеки native-libs.jar в APK-файл.

Пример build.gradle с данным кодом:

Обратите внимание, что у меня дирректории jni, libs расположены по адресу » / Project/ /src/main». Если в Вашем проекте эти папки лежат в другом месте, то Вам следует учесть это в формировании путей для всех команд.

Если всё сделано правильно, то Android Studio в ходе сборки проекта автоматически создаст в каталоге build правильную библиотеку и включит её в готовую программу. Таким образом, после каждой перекомпиляции нативного кода отпадает необходимость совершения каких-либо дополнительных действий и настроек, gradle сделает всё сам.

Теперь, как и было обещано в начале статьи, краткое резюме, описывающее лишь полный алгоритм без лишних комментариев:

Краткое резюме
  1. Открываем папку » / Project/ /src/main» и создаём там подпапку jni.
  2. Открываем файл » / Project/ /build.gradle», модифицируем раздел dependencies, после чего добавляем туда код:

Для включения также статических библиотек *.a (при их наличии) меняем строку

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

from fileTree(dir: ‘src/main/libs’, include: ‘**/*.*’)

  • В подпапке jni размещаем файлы *.mk, *.h, *.c, пишем нативный код.
  • Открываем папку » / Project/ /src/main» в терминале.
  • Вводим в терминале команду /ndk-build
  • Запускаем проект.
  • Важно!
    Данная инструкция предназначена для операционных систем Unix (в моём случае — MacOSX). Для операционной системы MS Windows пункты 4 и 5 не актуальны, так как для компиляции нативных библиотек требуются дополнительные утилиты. Также, скорее всего, будет целесообразным изменить пути хранения библиотек на более удобные и учесть это в скрипте сборки.

    На этом я завершаю статью и откланиваюсь. Надеюсь, кому-то данная статья сэкономит время.

    Удачного Вам нативного программирования, главное — каждый раз не забывайте себя спрашивать, стоит ли использовать нативный код. Вполне могут быть java-аналоги, использование которых проще, а в большинстве случаев – лучше, так как сокращается время разработки, улучшается понимаемость кода другими, снижается сложность архитектуры приложения, а мощности современных устройств хватает на выполнение большинства задач даже в Dalvik VM.

    Источник

    Читайте также:  Андроид как сбросить настройки звука
    Оцените статью