Разработка и портирование приложений Android* на основе NDK на архитектуру IA

Цель

Эта статья представляет собой инструкцию базового уровня по созданию собственных приложений Android* (на базе NDK) для устройств с архитектурой Intel® (IA). Также мы рассмотрим вопрос портирования на платформу IA приложений Android NDK, созданных для устройств с другой архитектурой.

Введение

Приложения Android* могут включать собственный код, созданный с помощью пакета Native Development Kit (NDK). Этот пакет дает разработчикам возможность повторного использования устаревшего кода, создавать код для низкоуровневого взаимодействия с оборудованием, а также реализовывать функции, которые невозможно или затруднительно создавать другими способами.

Эта статья содержит базовые сведения о создании приложений на базе NDK для архитектуры Intel, а также простые примеры портирования приложений на базе NDK на устройства с архитектурой Intel. Для демонстрации мы будем использовать пошаговый сценарий разработки простого приложения.

Мы исходим из того, что вы уже установили среду разработки Android, включая Android SDK и NDK, а также настроили emulator-x86 для тестирования приложений. Дополнительные сведения см. в разделе сообщества Android на веб-сайте Intel. Для простоты среды разработки мы по большей части используем средства Linux* для командной строки.

Создание приложения Android на базе NDK для устройств с архитектурой IA — пошаговая инструкция для простого приложения

Предположим, что у нас есть код, использующий язык C и ассемблер для анализа CPUID (дополнительные сведения о CPUID см. по адресу http://ru.wikipedia.org/wiki/CPUID*). Ниже приведен исходный код нашего приложения на языке C: файла cpuid.c (приводится исключительно для демонстрации).

Нам нужно вызвать cpuid_parse из приложения Android (только для демонстрационных целей — функция cpuid_parse предполагает наличие заранее выделенного буфера) и отобразить выходные данные в приложении.

Ниже приведена пошаговая инструкция по созданию приложения Android от начала до конца с использованием указанного выше собственного кода.

1. Создание проекта Android по умолчанию

Пакет Android SDK включает средства командной строки для создания структуры проекта по умолчанию для типового простого приложения. Сначала мы создадим проект по умолчанию, а затем изменим исходный код Java, чтобы добавить вызовы JNI и нативный код.

На приведенном выше снимке экрана мы сначала создали каталог labs/lab2, а затем использовали средство командной строки android для создания проекта по умолчанию. Мы указали android-15 в качестве уровня API и назвали наше приложение CPUIdApp с пакетом com.example.cpuid.

Затем мы использовали средство командной строки ant для сборки проекта в режиме отладки и установили его с помощью adb (можно выполнить и переустановку, если приложение уже существует на целевом устройстве или эмуляторе). Мы исходим из того, что на компьютере запущен эмулятор (или к компьютеру подключено целевое устройство), и это единственное перечисленное устройство в выходных данных команды adb devices.

Ниже приведен снимок экрана эмулятора Android x86 с ICS после выполнения описанного выше процесса.

Теперь можно изменить приложение для использования нативного кода.

2. Вызов нативного кода из Java

В проекте Android по умолчанию создается исходный код Java для типичного проекта вида hello world с заданным пространством имен пакета (например, com.example.cpuid). На приведенном ниже снимке экрана показан исходный код, созданный для основного файла исходного кода Java.

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

Собственный код возвращает строку java, которую мы можем использовать в любом месте кода java. Как показано на снимке экрана, приведенном выше, мы изменили TextView для отображения строки, которую мы получаем из вызова собственного кода. Это выделено красным на рисунке.

Это очень простой способ объявления и использования собственных вызовов JNI в коде Java приложений Android. Затем мы будем использовать средство «javah» для создания заглушек заголовков JNI для собственного кода, добавления или изменения нативного кода для соответствия собственным заголовкам JNI.

3. Использование средства javah для создания заглушек заголовков JNI для собственного кода

Теперь нам нужно изменить собственный код так, чтобы он соответствовал спецификации вызовов JNI. Средство javah помогает автоматически создать нужные заглушки заголовков JNI на основе файлов исходного кода Java. Средству javah требуется скомпилированный файл класса Java для создания заголовков. Поэтому мы используем средство ant, чтобы быстро создать файлы классов Java, как показано на приведенном ниже снимке экрана (команда ant debug).

Используйте средство javah для создания заголовка JNI, как показано на снимке экрана (второе выделенное желтым поле). Будет создан каталог jni и заглушка заголовка на основе класса Java. На приведенном ниже снимке экрана показа созданная заглушка заголовка JNI.

Создайте соответствующий файл исходного кода C (com_example_cpuid_CPUIdApp.c) для заголовка, созданного выше. Ниже приведен исходный код:

Мы вызываем собственный код cpuid_parse и возвращаем обработанный буфер в виде строки JNI. Теперь все готово к компиляции собственного кода с помощью NDK x86.

4. Сборка собственного кода с NDK для x86

Дополнительные сведения об установке и использовании NDK для IA см. в разделе сообщества Android на сайте Intel http://software.intel.com/ru-ru/android/articles/android-ndk-for-intel-architecture).

Пакет Android NDK использует системы сборки, для которой требуется настраиваемый файл makefile Android.mk, который должен находиться в папке jni проекта для компиляции собственного кода. В файле Android.mk указываются все файлы собственного исходного кода C/C++ для компиляции, заголовки и тип сборки (например: shared_library).

Ниже приведен код файла makefile Android для нашего проекта (jni/Android.mk)

Это простой сценарий с двумя файлами исходного кода на языке C со сборкой общей библиотеки.

Теперь мы можем выполнить команду ndk-build APP_ABI=x86 для сборки собственного кода и создать общую библиотеку. Система сборки Android также предоставляет дополнительный необязательный файл Application.mk, с помощью которого можно указать дополнительные параметры конфигурации. Например, мы можем указать все поддерживаемые ABI в файле Application.mk. Команда ndk-build создает собственные общие библиотеки для всех архитектур.

На приведенном выше снимке экрана показана успешная компиляция собственного кода для x86, а также создание и установка общей библиотеки. Теперь все готово к сборке нашего приложения Android и его установки и запуска на эмуляторе x86 или устройстве назначения.

5. Пересборка, установка и запуск приложения Android NDK для IA

Мы можем использовать команду ant debug clean, чтобы очистить старые файлы сборки, а повторная команда ant debug заново запустит полную пересборку проекта Android. Используйте adb для переустановки приложения на устройстве назначения или эмуляторе x86, как показано на снимке экрана ниже.

На приведенном ниже снимке экрана показан значок приложения в эмуляторе x86 и результат выполнения приложения в эмуляторе x86.

Мы успешно собрали приложение Android на базе NDK.

Использование набора инструментов NDK x86 для портирования существующих приложений на базе NDK на устройства с архитектурой IA

Приложения Android с нативным кодом, как правило, имеют стандартную структуру проекта с папкой jni, содержащей собственный исходный код, и соответствующими файлам сборки Android.mk/Application.mk. В предыдущем разделе мы рассмотрели простой пример с собственным исходным кодом и соответствующим файлом Android.mk.

Пакет Android NDK позволяет сразу указать все целевые ABI в файле Application.mk и автоматически создать собственные общие библиотеки для всех целевых платформ. Система сборки Android автоматически упакует все целевые собственные библиотеки внутри APK, а во время установки диспетчер пакетов Android установит только ту собственную библиотеку, которая соответствует архитектуре платформы назначения.

Можно вызвать ndk-build или указать библиотеку в Application.mk.

APP_ABI := all

ИЛИ

APP_ABI := armeabi armeabi-v7a x86

Дополнительные сведения см. по адресу http://developer.android.com/sdk/ndk/index.html.

Для портрования существующего приложения Android с нативным кодом, которое в настоящий момент не предназначено для архитектуры x86, применяется процесс изменения приложения для поддержки IA. В большинстве случаев этот процесс довольно прост (как мы рассмотрели выше), если приложение не использует специализированные конструкции или ассемблер исключительно для одной определенной архитектуры. Возможны другие проблемы, например, выравнивание памяти или использование инструкций, применяемых для определенных платформ. Дополнительные сведения см. по адресу: http://software.intel.com/ru-ru/android/articles/ndk-android-application-porting-methodologies.

Выводы

В этой статье мы рассмотрели создание и портирование приложений Android на базе NDK на архитектуру IA. Мы рассмотрели пошаговый процесс создания приложения на базе NDK для IA от начала до конца. Также мы рассмотрели простой процесс портирования существующих приложений Android на базе NDK на архитектуру IA с помощью средств пакета NDK.