Перейти к содержимому

Android ndk что это

  • автор:

Создание приложения Android Native Activity

После установки кроссплатформенной рабочей нагрузки Разработка мобильных приложений на языке C++ Visual Studio можно использовать для создания полнофункциональных приложений Android Native Activity. Пакет Android Native Development Kit (NDK) — это набор средств, с помощью которых можно реализовывать большинство возможностей приложения Android, используя чистый код C или C++. Для обеспечения взаимодействия кода C или C++ с Android используется определенный код Java JNI, выступающий в роли связующего. В Android NDK появилась возможность создавать приложения Native Activity с помощью API Android уровня 9. Код Native Activity популярен для создания игровых приложений и приложений с интенсивным использованием графики на основе Unreal Engine или OpenGL. В этом пошаговом руководстве показано создание простого приложения Native Activity, в котором используется OpenGL. В дополнительных разделах последовательно рассматриваются такие этапы жизненного цикла разработки, как редактирование, сборка, отладка и развертывание кода Native Activity.

Требования

Прежде чем создавать приложение Android Native Activity, необходимо убедиться, что вы выполнили все системные требования и установили рабочую нагрузку Разработка мобильных приложений на языке C++ в Visual Studio. Дополнительные сведения см. в статье Установка Visual C++ для разработки кроссплатформенных мобильных приложений на языке C++. Убедитесь, что необходимые сторонние инструменты и пакеты SDK включены в установку, а также что установлен эмулятор Android.

Создание проекта Native Activity

В этом руководстве вы сначала создадите новый проект Android Native Activity, а затем создадите и запустите приложение по умолчанию в эмуляторе Android.

  1. В Visual Studio выберите Файл>Создать>Проект.
  2. В диалоговом окне Новый проект в меню Шаблоны последовательно выберите Visual C++>Кроссплатформенное приложение, а затем выберите шаблон Приложение Native-Activity (Android).
  3. Присвойте приложению имя, например MyAndroidApp, а затем нажмите OK. Screenshot of using the New Project dialog to create a Native Activity project.Visual Studio создаст новое решение и откроет обозреватель решений. Native Activity project in Solution Explorer.
  1. В Visual Studio выберите Файл>Создать>Проект.
  2. В диалоговом окне Создание нового проекта выберите шаблон Приложение Native-Activity (Android), а затем нажмите Далее.
  3. В диалоговом окне Настроить новый проект введите имя, например MyAndroidApp в разделе Имя проекта, а затем выберите Создать. Visual Studio создаст новое решение и откроет обозреватель решений.

В новое решение приложения Android Native Activity входят два проекта.

  • MyAndroidApp.NativeActivity содержит ссылки и связующий код для запуска приложения как приложения Native Activity на Android. Реализация точек входа из связующего кода находится в файле main.cpp. Предкомпилированные заголовки находятся в файле pch.h. Этот проект приложения Native Activity компилируется в общую библиотеку (файл SO), которая передается в проект упаковки.
  • MyAndroidApp.Packaging создает файл с расширением .apk для развертывания на устройстве или в эмуляторе Android. Он содержит ресурсы и файл AndroidManifest.xml, в котором задаются свойства манифеста. В него также входит файл build.xml, управляющий процессом сборки Ant. По умолчанию он задан как начальный проект, который можно развернуть и запустить непосредственно из Visual Studio.

Создание и запуск приложения Android Native Activity по умолчанию

Разработайте и запустите приложение, созданное шаблоном, чтобы проверить установку и настройку. Для первоначального теста запустите приложение в одном из профилей устройств, установленных эмулятором Android. Если вы предпочитаете тестировать приложение на другой платформе, загрузите целевой эмулятор или подключите устройство к компьютеру.

Сборка и запуск приложения Native Activity по умолчанию

  1. Выберите пункт x86 из раскрывающегося списка Платформы решения , если он еще не выбран. Solution Platforms dropdown x86 selection.Если список Платформы решения не отображается, щелкните пункт Платформы решения из раскрывающегося списка Добавить или удалить кнопки и выберите свою платформу.
  2. В строке меню последовательно выберите Сборка>Собрать решение. В окне «Выходные данные» отобразятся выходные данные процесса сборки для двух проектов в решении.
  3. Выберите один из профилей эмулятора Android в качестве цели развертывания. Если вы установили другие эмуляторы или подключили устройство Android, то можете выбрать их в раскрывающемся списке платформы развертывания.
  4. Нажмите F5, чтобы начать отладку, или Shift+F5 для запуска без отладки. Вот как выглядит приложение по умолчанию в эмуляторе Android. The emulator running your app.Visual Studio запускает эмулятор, который за несколько секунд загружает и развертывает код. После запуска приложения можно задать точки останова и использовать отладчик для проверки кода, языковых стандартов и контрольных значений.
  5. Для остановки отладки нажмите SHIFT+F5. Эмулятор является отдельным процессом, который продолжает выполняться. Вы можете изменять, компилировать и развертывать код несколько раз в одном эмуляторе.

Android NDK

«Хотя это и позволяет писать нативные приложения, работающие быстрее чем Java, писать только на C/C++ нельзя, точка входа обязательно должна быть написана на Java», — это не правда. Полностью нативные андроид-приложения можно делать чуть ли не со времён 9-й версии API (android 2.3). Proof: https://developer.android.com/ndk/samples/sample_na

#2
19:07, 24 фев 2021

General GDA
Пофиксил

  • General GDA
  • Постоялец

#3
19:50, 24 фев 2021

Я бы ещё текст прогнал через спелл чекер (пунктуация, опечатки) и согласовал предложение. А то «это . » и начинается с маленькой буквы, и читается как-то не очень. Но это мелочи.

Главное, что «работающие быстрее, чем Java», — это субъективное оценочное суждение. Мало того, что на android нету Java (да, программу на этом языке можно скомпилировать для работы на Android; но на устройствах нет Java VM, модель памяти отличается от Java и т.п.). Так ещё на C/C++ надо постараться написать быстрее. К примеру, в современных андроидах очень сложная среда исполнения, где есть пред-компиляция в нативный код ещё на момент инсталляции приложения. При обновлении ОС может (и делает) перекомпиляция такого кода. Ещё пример: лично я при должном старании определённый класс задач под андроид вполне могу написать на Java/Kotlin так, что будет быстрее, чем на C++. Как в плане скорости выполнения кода, так и в плане скорости его написания.

Раз форум у нас тут гемдеву посвящён. То я могу набросить пример: на Unity так вообще всё на C# пишется. И ничего. Тонны успешных проектов (гемдев проектов!) под мобильные телефоны.

Если и писать про «быстрее», то со ссылками на конкретные исследования или case studies.

#4
13:12, 25 фев 2021

General GDA, хотелось бы поподробнее, как вы напишите приложение, которое написано на Java так, чтобы оно работало быстрее внутреннего цикла нативной программы? В плане скорости работы кода.

Про скорость написания — это зависит от того, что уже для этого сделано.

#5
15:50, 25 фев 2021

Mirrel
ну, как пример из головы — если работа приложения состоит в обработке строк или структур, которые оно получает с помощью одних вызовов API и отображает с помощью других, то большую часть времени нативное приложение может заниматься перепаковыванием их в свое представление, а java — будет работать с данными «как есть».
Другой пример — оптимизатор java вполне может быть круче оптимизатора fpc и соответственно одни и те же вычисления будут преобразованы в более эффективный машинный код.

#6
18:23, 25 фев 2021

kipar, я не об этом спрашивал!

Есть (у абсолютно нативного приложения) свой внутренний цикл (как и в других системах). Из этого цикла и происходят всё вызовы этого самого приложения (Start, Stop, Pause, Resume . ).

Как, человек сможет, используя java-код, обойти скорость работы внутреннего цикла?

И, всеми данными, можно пользоваться из нативного кода. В дополнению к этому, многие данные на Android находятся именно в нативном виде, а внутренние библиотеки соединяют этот код для удобства работы с Java-кодом.

но это больше для информации.

#7
18:43, 25 фев 2021

Mirrel
> Start, Stop, Pause, Resume
эти операции делаются достаточно редко, чтобы игнорировать JNI-оверхед при их вызове. Да даже если Update — один JNI-вызов каждый кадр — это копейки.

#8
18:45, 25 фев 2021

Что если, я скажу, что можно полностью игнорировать JNI-вызовы?

#9
18:51, 25 фев 2021

Mirrel
> Что если, я скажу, что можно полностью игнорировать JNI-вызовы?
и писать при этом на яве?

#10
19:41, 25 фев 2021

Зачем? Лично я буду писать на Паскале. Другой народ на C/C++. Кто умеет, тот на каком ещё языке, кроме всех вышеперечисленных.

#11
22:46, 25 фев 2021

General GDA
То есть dalvik и art не выполняют (свой) java байт-код? Про скорость C/C++ согласен.

оффтоп: как цитаты писать?

#12
23:31, 25 фев 2021

egoros7
Dalvik, вроде как — вполне себе jvm и исполняет байткод. Хотя и не совсем compliant. А art — он AOT.

#13
23:38, 25 фев 2021

kkolyan
>а art — он AOT
Ну при включении машинный код всё же компилируется из байт-кода. Или я не прав?

#14
23:41, 25 фев 2021

egoros7
Скорее всего да, т.к. это проще чем компилить из сорцов. Но я наверняка не знаю.

Учимся работать с Android NDK или как использовать C код в java проектах

Android NDK native

Android NDK представляет собой набор утилит, позволяющих Вам включать код, написанный на C и C++, в ваше приложение. Такой код называется нативным(native), поскольку он не может быть выполнен на виртуальной машине и компилируется непосредственно в машинный код требуемой процессорной архитектуры.

Данный урок относится к разряду продвинутых. Подразумевается, что читатель уже имеет некоторые навыки, в частности

  1. Вы умеете программировать на Java и C
  2. Вы умеете работать с командной строкой
  3. Вы знаете, как узнать версии Cygwin, awk и других инструментов, которыми нам придется пользоваться
  4. Вы умеете разрабатывать приложения для Android
  5. У Вас настроена среда разработки для Android (в момент написания автор использовал Android 2.2)
  6. Вы используете Eclipse или можете транслировать инструкции по работе с eclipse на свою IDE.

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

Когда нужно использовать Android NDK?

Обычно разработчики решают использовать нативный код в двух случаях: они хотят увеличить производительность своего приложения, или у них есть готовый C/C++ проект, который требуется с минимальными затратами портировать на Android. Давайте не будем спешить и разберемся, когда же целесообразно использовать NDK, а когда этого не нужно делать.

Наиболее часто программистами высказывается мнение, что NDK стоит использовать, когда приложение сильно нагружает процессор. Существуют алгоритмы, позволяющие полностью загрузить процессор через DalvikVM, в этом случае использование нативного кода действительно с большой вероятностью позволит получить выигрыш в производительности. Однако, не нужно забывать, что использование JIT компилятора также позволяет повысить производительность java кода. Многие думают, что использование в приложении машинного кода автоматически означает увеличение скорости работы приложения. На самом деле это не так. Переключение с выполнения java кода на машинный код и обратно несет с собой накладные расходы, поэтому использовать NDK стоит, только если у вас выполняется какой-нибудь долгий сложный расчет, полностью написанный на C, и в java коде не предполагается частое дерганье нативных функций.

Другой причиной, которая может побудить Вас использовать NDK является необходимость портирования готового приложения. Вполне логично не переписывать уже проверенные и отлаженные куски кода на java, а использовать NDK. Этот подход также позволит Вам в дальнейшем без особых затрат вносить параллельно правки в исходное и портированное на android приложение. В частности, такой подход оправдан в отношении приложений, использующих OpenGL ES.

Шаг 1: Установка Android NDK и настройка среды разработки

Прежде всего, Вам необходимо скачатьAndroid NDK. Для установки и нормальной работы нам также понадобятся утилиты Cygwin 1.7 или старше, awk последней версии, а также GNU Make 3.81 или старше.

После того, как Вы скачали архив с NDK, распакуйте его в какую-нибудь папку. Можно распаковать этот архив туда же, где лежит Android SDK. Путь к этой папке необходимо прописать в системной переменной PATH. В Windows для этих целей лучше настроить конфигурацию Cygwin.

Шаг 2: Создание нового проекта

Создайте новый Android проект. Чтобы избежать проблем в будущем сохраните проект так, чтобы путь к нему не содержал в себе символов пробела. Для примера создайте проект, в качестве названия пакета укажите «com.mamlambo.sample.ndk1», а в качестве Activity — «AndroidNDK1SampleActivity».

В корне проекта создайте папку с названием «jni». Именно здесь будет содержаться файлы с нативным кодом. Если Вы знакомы с JNI, то вам будет приятно узнать, что Android NDK по сути представляет собой JNI с ограниченным набором заголовочных файлов для компиляции C кода.

Шаг 3: Добавляем C код в Android проект

Создайте в папке jni файл с именем native.c и добавьте в него следующий код

#include #include #include  #define DEBUG_TAG "NDK_AndroidNDK1SampleActivity" void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv* env, jobject this, jstring logThis) { jboolean isCopy; const char* szLogThis=(*env)->GetStringUTFChars(env, logThis,&isCopy); __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG,"NDK:LC: [%s]", szLogThis); (*env)->ReleaseStringUTFChars(env, logThis, szLogThis); } 

Созданная таким образом функция берет параметр String у java объекта, конвертирует его в C-string и записывает в LogCat. Зубодробительное имя функции выбрано не случайно, оно несет в себе важную информацию: сначала указывается название паттерна («Java»), затем идут название пакета, имя класса и название метода. Каждая часть имени отделяется знаком подчеркивания.

Первые два параметра у функции имеют особое значение. Первый параметр определяет JNI среду и часто используется со вспомогательными функциями. Второй параметр является объектом Java, частью которого является функция.

Шаг 4: Вызов нативного кода из Java

Давайте создадим в нашем проекте кнопку, при нажатии на которую будем вызывать следующий код:

helloLog("This will log to LogCat via the native call.");

Необходимо также объявить функцию helloLog в классе, где она вызывается. Сделать можно с помощью строки

private native void helloLog(String logThis);

Таким образом, мы сообщаем компилятору и линковщику, что реализацию этой функции стоит искать в папке с нативным кодом.

Наконец, нужно загрузить библиотеку, куда в конечном счете будет скомпилирован код. Добавьте следующую инициализацию в класс Activity.

static{ System.loadLibrary("ndk1"); }

System.loadLibrary() обеспечивает загрузку библиотеки по имени. Вы можете использовать любое название.

Шаг 5: Создаем Make file для нативного кода

Для компиляции нативного кода в папке jni должен находиться Make file с именем «Android.mk». Ниже приведен код этого фала для нашего примера, то есть когда функция находится в файле native.c и в качестве имени библиотеки указано ndk1

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS)

LOCAL_LDLIBS := -llog

LOCAL_MODULE := ndk1
LOCAL_SRC_FILES := native.c

include $(BUILD_SHARED_LIBRARY)

Шаг 6: компиляция нативного кода

После того, как Вы написали код и добавили make файл в папку jni можно приступать к компиляции. Для этого нужно в командной строке (Если вы работаете в windows, запустите Cygwin) запустить ndk-build из папки проекта. Утилита ndk-build входит в состав Android NDK. Если Вы все сделали правильно, то вы должны увидеть что-то вроде этого

NDK компиляция

Шаг 7: Запуск приложения

Теперь можно запустить проект, нажать на кнопку и посмотреть, как изменится LogCat.

Может произойти одна из двух вещей: 1) ваш проект может запуститься и работать, как Вы того ожидаете. В этом случае примите мои поздравления. 2) Возникнет ошибка, которая в LogCat отобразиться как «Could not execute method of activity.» Ничего страшного. Обычно Eclipse сконфигурирован так, что при запуске проекта автоматически происходит его перекомпиляция. В случае, если эта опция отключена, то нужно вручную заставить Eclips перекомпилировать проект. Для этого перед запуском нужно вызвать менюProject->Clean from the Eclipse toolbar.

Шаг 8: Как вернуть объект из нативной функции

Следующий пример демонстрирует возможность нативных функций возвращать объекты, например String. Добавьте код в файл native.c

jstring Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_getString(JNIEnv* env, jobject this, jint value1, jint value2) { char*szFormat="The sum of the two numbers is: %i"; char*szResult; // добавляем две переменные jlong sum= value1+value2; // malloc для строки результата szResult= malloc(sizeof(szFormat)+20); // standard sprintf sprintf(szResult, szFormat, sum); // получаем объект string jstring result=(*env)->NewStringUTF(env, szResult); // очищаем память free(szResult); return result; }

С помощью команды malloc мы создали буфер, куда затем с помощью sprintf поместили строку. Чтобы функция возвращала корректный результат, мы использовали JNI helper функцию NewStringUTF(), которая фактически создает Java объект на основании C строки. После этого мы очистили память с помощью команды free().

Для успешной компиляции проекта необходимо в native.c подключить заголовочный файл stdio.h. В классе Activity нужно также объявить новую функцию:

private native String getString(int value1, int value2);

после этого с функцией getString можно работать, например следующим образом:

String result= getString(5,2); Log.v(DEBUG_TAG,"Result: "+result); result= getString(105,1232); Log.v(DEBUG_TAG,"Result2: "+result);

Замечания

Android NDK для своей работы требует Android SDK 1.5. С помощью NDK можно получить доступ ко многим API, например к OpenGL ES.

Нативный код компилируется в машинный код, соответствующий архитектуре процессора, и поскольку на разных телефонах используются процессоры разной архитектуры, у Вас может возникнуть проблемы с переносимостью программы. По умолчанию NDK производит компиляцию для ARMv5TE. Когда Вы запускаете свое приложение на эмуляторе, а не на реальном устройстве, этот машинный код выполняется не напрямую, а через еще один эмулятор процессора.

Заключение

Ну вот собственно и все. Думаю теперь вам понятно, как работать с нативным кодом. Во многих случаях его применение оправдано, однако бездумное применеие нативного кода в своих проектах может оказаться губительным.

Авторы:Lauren Darcey и Shane Conder
Источник:Advanced Android: Getting Started with the NDK
Перевод:Александр Ледков

О метке

Android NDK (native development kit) – это набор инструментов, которые позволяют реализовать часть вашего приложения, используя такие языки как С/С++. Используйте данную метку, когда ваш проект связан с разработкой под Android на вышеупомянутых языках.

Android NDK (native development kit) — это набор инструментов, который позволяет использовать код С/C++ с Android и предоставляет библиотеки для платформы, которые вы можете использовать для управления собственными действиями и доступа к физическим компонентам устройства, таким как датчики и сенсоры. NDK может быть полезен для случаев, когда вам необходимо выполнить одно или несколько из следующих действий:

  • для извлечения большей производительности из устройства для достижения низкой задержки или запуска приложений с ресурсоемкими вычислением, такие как игры или физическое моделирование
  • для повторного использования собственных или других библиотек разработанных на языках C/C++.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *