- Как установить android ndk в linux?
- 6 ответов
- Install and configure the NDK and CMake
- Install NDK and CMake automatically
- Install the NDK and CMake
- Configure a specific version of CMake
- Groovy
- Kotlin
- Install a specific version of the NDK
- Configure specific versions of the NDK in your project
- Groovy
- Kotlin
- Default NDK version per AGP version
- Введение в Android NDK
- Что такое Android NDK?
- Для чего используют NDK?
- Что такое JNI?
- Преимущества JNI
- Как устроен JNI
- Локальные и глобальные ссылки
- Обработка ошибок
- Примитивные типы JNI
- Ссылочные типы JNI
- Модифицированный UTF-8
- Функции JNI
- Пример использования функций JNI
- Потоки
- Первые шаги
- Android.mk
- Application.mk
- NDK-BUILDS
- Как собрать проект?
- Вызов нативных методов из Java кода
Как установить android ndk в linux?
Я загрузил android NDK отсюда:http://developer.android.com/tools/sdk/ndk/index.html
для Linux 64-разрядная версия (x86) android-ndk-r10c-linux-x86_64.бункер. Как я его устанавливаю? Инструкции не работают. Моя ОС
6 ответов
Стандартный Путь
NDK Android теперь поставляется как самораспаковывающийся исполняемый файл. Вероятно, вам нужно установить исполняемый бит:
вышеуказанное приведет к извлечению NDK в текущий рабочий каталог.
Извлечение Инструкцию
Так .bin файл действительно Просто 7-Zip самораспаковывающийся архив, вы можете вручную извлечь содержимое, если нужны:
7-Zip доступен в Ubuntu, например, через apt-get:
обновление
Как минимум r14b на страница загрузки NDK, мы вернулись к стандартным архивам ZIP.
вы можете установить NDK с помощью диспетчера SDK из Android Studio
в открытом проекте выберите инструменты > Android > SDK Manager в строке меню. Перейдите на вкладку Инструменты SDK. Установите флажки рядом с LLDB, CMake и NDK. Применить
перейдите в каталог, в который вы его загрузили. Затем выполните:
Он должен распаковать прямо там. Цепочка инструментов будет находиться в Android-ndk-r10c-linux-x86_64/toolchains. Корневая папка может иметь несколько другое имя.
Я сделал, как показано ниже
установить 7-Zip через apt-get такой
перейдите в папку, где находится ваш NDK bin, а затем выполните команду
Ubuntu будет ошибка:bash: ./андроид-НДК-r10c-ОС Linux-x86_64 с.ОГРН: нет такого файла или каталога
slove: apt-get install p7zip-full
у меня есть androidBBQ, который основан на archlinux, установленный с помощью vmware. Но я думаю мои инструкции должны быть одинаковыми для любого дистрибутива Linux. Я использовал встроенный менеджер SDK AndroidStudio, чтобы попытаться установить NDK. Не удалось загрузить, потому что в /tmp не было места. Оказывается, большинство дистрибутивов Linux имеют ramdisk baesd tmpfs (временная файловая система в ОЗУ, которая монтируется в /tmp) и нет отдельного раздела, который можно было бы расширить. / tmp установлен обычно с помощью 50% доступной оперативной памяти.
установите NDK с помощью встроенного SDK-менеджера Android Studio ->не так удобно
a) расширить / tmp
Я отредактировал свою fstab как root, используя эту команду:
Я добавил эту строку к моей fstab
Примечание: если такой строки не существует, добавьте строку выше в конце fstab. Если такая линия существует, это означает, что вы уже расширил ваш /tmp, и он все еще был недостаточным. Таким образом, измените значение «размер», подняв его на несколько GBs.
Затем я перезагрузился. Как только я это сделал, мой /tmp был расширен до размера 8GB. Для целей развития, я думаю мы должны легко расширить наш / tmp потому что нам все равно придется сделать это через некоторое время. Размер /tmp не зависит от свободного места на нашем жестком диске (виртуальном или физическом).
b) запустите NDK install еще раз
Я побежал NDK снова устанавливается из AndroidStudio. Он должен был загрузить NDK zip заново. Unfrotunate, что нет функции resume/recheck для восстановления сломанных установок. Моя скорость загрузки была медленной, поэтому я свернул окно виртуального linux и продолжил читать новости. Позже, я думаю, произошел обмен памятью / страницей. Ошибка загрузки. Я перезапустил Linux и перезапустил NDK install таким же образом. На этот раз я позволил виртуальной машине Linux остаться на переднем плане. NDK установлен нормально с этим журналом :
ручная установка NDK в Linux (предпочтительно) Я поражен, что официальный раздел Android dev не потрудился указать точное местоположение установки Android NDK. Android Studio ищет NDK по адресу:
Источник
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:
- Download and install CMake from the official CMake website.
- 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.
Источник
Введение в Android NDK
Для разработки приложений под ОС Android, Google предоставляет два пакета разработки: SDK и NDK. Про SDK существует много статей, книжек, а так же хорошие guidelines от Google. Но про NDK даже сам Google мало что пишет. А из стоящих книг я бы выделил только одну, Cinar O. — Pro Android C++ with the NDK – 2012.
Эта статья ориентирована на тех, кто ещё не знаком (или мало знаком) с Android NDK и хотел бы укрепить свои знания. Внимание я уделю JNI, так как мне кажется начинать нужно именно с этого интерфейса. Так же, в конце рассмотрим небольшой пример с двумя функциями записи и чтения файла. Кто не любит много текста, тот может посмотреть видео версию.
Что такое Android NDK?
Android NDK (native development kit) – это набор инструментов, которые позволяют реализовать часть вашего приложения используя такие языки как С/С++.
Для чего используют NDK?
Google рекомендует прибегать к использованию NDK только в редчайших случаях. Зачастую это такие случаи:
- Нужно увеличить производительность (например, сортировка большого объема данных);
- Использовать стороннюю библиотеку. Например, много уже чего написано на С/С++ языках и нужно просто заиспользовать существующий материал. Пример таких библиотек, как, Ffmpeg, OpenCV;
- Программирование на низком уровне (например, всё что выходит за рамки Dalvik);
Что такое JNI?
Java Native Interface – стандартный механизм для запуска кода, под управлением виртуальной машины Java, который написан на языках С/С++ или Assembler, и скомпонован в виде динамических библиотек, позволяет не использовать статическое связывание. Это даёт возможность вызова функции С/С++ из программы на Java, и наоборот.
Преимущества JNI
Основное преимущество перед аналогами (Netscape Java Runtime Interface или Microsoft’s Raw Native Interface and COM/Java Interface) является то что JNI изначально разрабатывался для обеспечения двоичной совместимости, для совместимости приложений, написанных на JNI, для любых виртуальных машин Java на конкретной платформе (когда я говорю о JNI, то я не привязываюсь к Dalvik машине, потому как JNI был написан Oracle для JVM который подходит для всех Java виртуальных машин). Поэтому скомпилированный код на С/С++ будет выполнятся в не зависимости от платформы. Более ранние версии не позволяли реализовывать двоичную совместимость.
Двоичная совместимость или же бинарная совместимость – вид совместимости программ, позволяющий программе работать в различных средах без изменения её исполняемых файлов.
Как устроен JNI
JNI таблица, организована как таблица виртуальных функций в С++. VM может работать с несколькими такими таблицами. Например, одна будет для отладки, вторая для использования. Указатель на JNI интерфейс действителен только в текущем потоке. Это значит, что указатель не может гулять с одного потока в другой. Но нативные методы могут быть вызваны из разных потоков. Пример:
- *env – указатель на интерфейс;
- оbj – ссылка на объект в котором описан нативный метод;
- i and s – передаваемые аргументы;
Примитивные типы копируются между VM и нативным кодом, а объекты передаются по ссылке. VM обязана отслеживать все ссылки которые передаются в нативный код. Все переданные ссылки в нативный код не могут быть освобождены GC. Но нативный код в свою очередь должен информировать VM о том что ему больше не нужны ссылки на переданные объекты.
Локальные и глобальные ссылки
JNI делит ссылки на три типа: локальные, глобальные и слабые глобальные ссылки. Локальные действительны пока не завершиться метод. Все Java объекты которые возвращает функции JNI являются локальными. Программист должен надеется на то что VM сама подчистит все локальные ссылки. Локальные ссылки доступны лишь в том потоке в котором были созданы. Однако если есть необходимость то их можно освобождать сразу методом JNI интерфейса DeleteLocalRef:
Глобальные ссылки остаются пока они явно не будут освобождены. Что бы зарегистрировать глобальную ссылку следует вызвать метод NewGlobalRef. Если же глобальная ссылка уже не нужна, то её можно удалить методом DeleteGlobalRef:
Обработка ошибок
JNI не проверяет ошибки такие как NullPointerException, IllegalArgumentException. Причины:
- снижение производительности;
- в большинстве функций C библиотек очень и очень трудно защитится от ошибок.
JNI позволяет использовать Java Exception. Большинство JNI функций возвращают код ошибок а не сам Exception, и поэтому приходится обрабатывать сам код, а в Java уже выбрасывать Exception. В JNI следует проверять код ошибки вызываемых функций и после них следует вызвать ExceptionOccurred(), которая в свою очередь возвращает объект ошибки:
Например, некоторые функции JNI доступа к массивам не возвращают ошибки, но могут вызвать исключения ArrayIndexOutOfBoundsException или ArrayStoreException.
Примитивные типы JNI
В JNI существуют свои примитивные и ссылочные типы данных.
Java Type | Native Type | Description |
---|---|---|
boolean | jboolean | unsigned 8 bits |
byte | jbyte | signed 8 bits |
char | jchar | unsigned 16 bits |
short | jshort | signed 16 bits |
int | jint | signed 32 bits |
long | jlong | signed 64 bits |
float | jfloat | 32 bits |
double | jdouble | 64 bits |
void | void | N/A |
Ссылочные типы JNI
Модифицированный UTF-8
JNI использует модифицированную кодировку UTF-8 для представления строк. Java в свою очередь использует UTF-16. UTF-8 в основном используется в С, потому что он кодирует \u0000 в 0xc0, вместо привычной 0x00. Изменённые строки кодируются так, что последовательность символов, которые содержат только ненулевой ASCII символы могут быть представлены с использованием только одного байта.
Функции JNI
Интерфейс JNI содержит в себе не только собственный набор данных, но и свои собственные функции. На их рассмотрение уйдёт много времени, так как их не один десяток. Ознакомится с ними вы сможете в официальной документации.
Пример использования функций JNI
Небольшой пример, что бы вы усвоили пройденный материал:
Разберём построчно:
- JavaVM – предоставляет интерфейс для вызова функций, которые позволяют создавать и уничтожать JavaVM;
- JNIEnv – обеспечивает большинство функций JNI;
- JavaVMInitArgs – аргументы для JavaVM;
- JavaVMOption – опции для JavaVM;
Метод JNI_CreateJavaVM() инициализирует JavaVM и возвращает на неё указатель. Метод JNI_DestroyJavaVM() выгружает созданную JavaVM.
Потоки
Всеми потоками в Linux управляет ядро, но они могут быть прикреплены к JavaVM функциями AttachCurrentThread и AttachCurrentThreadAsDaemon. Пока поток не присоединён он не имеет доступа к JNIEnv. Важно, Android не приостанавливает потоки которые были созданы JNI, даже если срабатывает GC. Но перед тем как поток завершиться он должен вызвать метод DetachCurrentThread что бы отсоединиться от JavaVM.
Первые шаги
Структура проекта у вас должна выглядеть следующим образом:
Как мы видим из рисунка 3, весь нативный код находится в папке jni. После сборки проекта, в папке libs создастся четыре папки под каждую архитектуру процессора, в которой будет лежать ваша нативная библиотека (количество папок зависит от количество выбранных архитектур).
Для того, чтобы создать нативный проект, нужно создать обычный Android проект и проделать следующие шаги:
- В корне проекта нужно создать папку jni, в которую поместить исходники нативного кода;
- Создать файл Android.mk, который будет собирать проект;
- Создать файл Application.mk, в котором описываются детали сборки. Он не является обязательным условием, но позволяет гибко настроить сборку;
- Создать файл ndk-build, который будет запускать процесс сборки (тоже не является обязательным).
Android.mk
Как упоминалось уже выше, это make файл для сборки нативного проекта. Android.mk позволяет группировать ваш код в модули. Модули могут быть как статические библиотеки (static library, только они будут скопированные в ваш проект, в папку libs), разделяемые библиотеки (shared library), автономный исполняемый файл (standalone executable).
Пример минимальной конфигурации:
Рассмотрим детально:
- LOCAL_PATH := $(call my-dir) – функция call my-dir возвращает путь папки в которой вызывается файл;
- include $(CLEAR_VARS) – очищает переменные которые использовались до этого кроме LOCAL_PATH. Это необходимо так как все переменные являются глобальными, потому что сборка происходит в контексте одного GNU Make;
- LOCAL_MODULE – имя выходного модуля. В нашем примере имя выходной библиотеки установлено как NDKBegining, но после сборки в папке libs создадутся библиотеки с именами libNDKBegining. Android добавляет к названию префикс lib, но в java коде при подключении вы должны указывать название библиотеки без префикса (то есть названия должны совпадать с установленными в make файлах);
- LOCAL_SRC_FILES – перечисление исходных файлов из которых следует создать сборку;
- include $(BUILD_SHARED_LIBRARY) – указывает тип выходного модуля.
В Android.mk можно определить свои переменные, но они не должны иметь такой синтаксис: LOCAL_, PRIVATE_, NDK_, APP_, my-dir. Google, рекомендует называть свои переменные, как MY_. Например:
Application.mk
NDK-BUILDS
Ndk-build из себя представляет обёртку GNU Make. После 4-й версии ввели флаги для ndk-build:
- clean – очищает все сгенеренные бинарные файлы;
- NDK_DEBUG=1 – генерирует отладочный код;
- NDK_LOG=1 – показывает лог сообщений (используется для отладки);
- NDK_HOST_32BIT=1 – Android имеет средства для поддержки 64-х битных версий утилит (например NDK_PATH\toolchains\mipsel-linux-android-4.8\prebuilt\windows-x86_64 и т.д.);
- NDK_APPLICATION_MK — указывается путь к Application.mk.
В 5-й версии NDK был введён такой флаг как NDK_DEBUG. Если он установлен в 1 то создаётся отладочная версия. Если флаг не установлен то ndk-build по умолчанию проверяет стоит ли атрибут android:debuggable=«true» в AndroidManifest.xml. Если вы используете ndk выше 8-й версии, то Google не рекомендует использовать атрибут android:debuggable в AndroidManifest.xml (потому что если вы используете «ant debug» или строите отладочную версию с помощью ADT плагина то они автоматически добавляют флаг NDK_DEBUG=1).
По умолчанию устанавливается поддержка 64-х разрядной версии утилит, но вы можете принудительно собрать только для 32-х установив флаг NDK_HOST_32BIT=1. Google, рекомендует всё же использовать 64-х разрядность утилит для повышения производительности больших программ.
Как собрать проект?
Раньше это было мучением. Нужно было установить CDT плагин, скачать компилятор cygwin или mingw. Скачать Android NDK. Подключить это всё в настройках Eclipse. И как на зло это всё оказывалось не рабочим. Я первый раз когда столкнулся с Android NDK, то настраивал это всё 3 дня (а проблема оказалось в том что в cygwin нужно было дать разрешение 777 на папку проекта).
Сейчас с этим всё намного проще. Идёте по этой ссылке. Качаете Eclipse ADT Bundle в котором уже есть всё то что необходимо для сборки.
Вызов нативных методов из Java кода
Для того что бы использовать нативный код из Java вам сперва следует определить нативные методы в Java классе. Например:
Перед методом следует поставить зарезервированное слово «native». Таким образом компилятор знает, что это точка входа в JNI. Эти методы нам нужно реализовать в С/С++ файле. Так же Google рекомендует начинать именовать методы со слова nativeХ, где Х – реальное название метода. Но перед тем как реализовывать эти методы вручную, следует сгенерировать header файл. Это можно сделать вручную, но можно использовать утилиту javah, которая находится в jdk. Но пойдём дальше и не будет использовать её через консоль, а будем это делать при помощи стандартных средств Eclipse.
Теперь можете запускать. В директории bin/classes будут лежать ваши header файлы.
Далее копируем эти файлы в jni директорию нашего нативного проекта. Вызываем контекстное меню проекта и выбираем пункт Android Tools – Add Native Library. Это позволит нам использовать jni.h функции. Дальше вы уже можете создавать cpp файл (иногда Eclipse его создаёт по умолчанию) и писать тела методов, которые уже описаны в header файле.
Пример кода я не стал добавлять в статью, чтобы не растягивать её. Пример вы можете посмотреть/скачать с github.
Источник