Connect with us

Разработка

Интегрируем Rust в Android-приложение

Цель этого пошагового руководства — предоставить простое, но эффективное руководство по интеграции кода Rust в разработку для Android.

Avatar photo

Опубликовано

/

     
     

Rust — это язык системного программирования общего назначения, который существует уже довольно давно. Его можно использовать для выполнения задач, которые реализуются сейчас на C и C++, но с гораздо большей безопасностью памяти. Это позволяет использовать Rust для написания программ или скриптов для многих операционных систем, включая Android. Вы можете задаться вопросом, как это возможно и есть ли простой способ сделать это. Вот об этом эта статья!

В настоящее время не так много информации о том, как писать код на Rust в Android-приложениях. Есть некоторая информация, предоставленная Google, но она сложна для понимания новичком. Цель этого пошагового руководства — предоставить простое, но эффективное руководство по интеграции кода Rust в разработку для Android. Никаких предварительных знаний C или C++ или JNI не требуется.

Настройка

Мы будем использовать Android Studio. Начнем с его настройки.

Плагин Rust

Во-первых, нам нужен плагин Rust. Откройте Android Studio. Откроется диалоговое окно, подобное показанному ниже. Выберите вкладку «Плагины», найдите «Rust», а затем установите официальный плагин Rust от JetBrains. В качестве альтернативы, если у вас уже открыт проект, нажмите «Файл» в верхнем левом углу Android Studio и выберите «Настройки». Нажмите «Плагины».

Плагин Rust требует, чтобы Rust был установлен в вашей системе. Вы можете перейти по этой ссылке, чтобы установить Rust в вашей системе.

Интегрируем Rust в Android-приложение

Создаем пустое приложение

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

Интегрируем Rust в Android-приложение

Назовем наш проект Rust Application и нажмем «Готово».

Появится окно, похожее на показанное ниже.

Интегрируем Rust в Android-приложение

Включаем Cargo Project

Давайте теперь добавим проект Cargo (менеджер пакетов для Rust) следуя этому руководству. Чтобы внедрить его в проект Rust, просто щелкните Терминал в Android Studio и введите это:

C:\Users\USER1\AndroidStudioProjects\RustApplication>cargo new rust_lib --lib

Это создает новую библиотеку, чтобы ее можно было использовать из нашего приложения. Мы назвали библиотеку rust_lib. Обратите внимание, где создается папка.

Чтобы просмотреть папку в Android Studio, перейдите на панель Project  и выберите Project  в раскрывающемся меню вместо Android.

Интегрируем Rust в Android-приложение

Вы увидите новую папку с именем rust_lib. Эта папка по умолчанию содержит новый репозиторий git, файл Cargo.toml и папку src, содержащую lib.rs. Теперь давайте изменим тип библиотеки, которую мы только что создали, используя файл Cargo.toml. Для разработки мобильных приложений библиотека должна быть динамической.

Добавьте следующее к содержимому файла Cargo.toml.

[lib]
name = "rust_lib"
crate-type = ["cdylib"]

Посмотреть суть здесь.

Добавление зависимостей

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

Используйте «*», чтобы получить последнюю версию зависимости.

Flapigen — это основная зависимость сборки для генерации соответствующего кода из нашего Rust кода и использования в Android-приложении. Flapigen работает с файлом интерфейса, но необходимость изменять файл интерфейса каждый раз при изменении кода может стать утомительной. Вот тут-то и появляется rifgen. Это упрощает создание файла интерфейса.

Дополнительные зависимости предназначены для ведения логов.

Создание файла сборки

Как упоминалось ранее, flapigen и rifgen являются зависимостями сборки и взаимодействуют с файлом build.rs. Щелкните правой кнопкой мыши папку rust_lib и выберите New > Rust File.

Интегрируем Rust в Android-приложение

Назовите файл build.rs.

Следуя руководству, предоставленному flapigen и rifgen, наш файл build.rs должен выглядеть примерно так:

Вам может быть интересно, что происходит в файле build.rs. Flapigen преобразует то, что находится в файле интерфейса, в Rust файл java_glue. Поэтому мы сначала указываем исходный файл для файла интерфейса (in_src), а затем выходной файл (java_glue.rs). Каталог java_glue.rs должен совпадать с переменной среды OUT_DIR. После этого используется rifgen для генерации файла интерфейса, с нашими предпочтениями в зависимости от языка, к которому мы добавляем проект Rust. Последний параметр Generator::new указывает начало папки, содержащей наш Rust код, а функция generate_interface принимает путь к файлу интерфейса, то есть in_scr. Папка java_folder указывает, куда должны помещаться созданные java-файлы. Вызов swig_gen.expand указывает flapigen сгенерировать соответствующие файлы. Обратите внимание на эти параметры, поскольку мы используем их в сборке Gradle.

Наконец, создайте файл с именем java_glue.rs в папке rust_lib/src и поместите в него следующее содержимое:

И добавьте:

mod java_glue;
pub use crate::java_glue::*;

в ваш файл lib.rs. Это соединит ваш Rust код со сгенерированным.

Добавляем Android Toolchain и линкеры

Чтобы скомпилировать Rust для Android, нам нужно добавить инструменты Android в rustup. Для этого просто запустите в Терминале следующее:

>rustup default nightly
>rustup target add aarch64-linux-android armv7-linux-androideabi

Поскольку rifgen крейт работает с nightly, вам нужно сначала установить Rust nightly.

Затем вы добавляете наборы инструментов Rust и стандартную библиотеку для 64-битной и 32-битной версий Android соответственно. Теперь давайте добавим компоновщики компилятора. Его нужно добавить в файл rust_lib/.cargo/config.toml.

Щелкните правой кнопкой мыши папку rust_lib, создайте новый каталог с именем .cargo, затем создайте новый файл в каталоге .cargo с именем config.toml.

Соответствующие компоновщики поставляются с Android NDK, поэтому их следует загрузить, прежде чем продолжить.

Добавьте следующее в созданный файл конфигурации.

Замените ANDROID SDK на путь к Android SDK (или папку, содержащую пакет NDK). Кроме того, замените OS VERSION на вашу версию ОС. Например, на моем компьютере с Windows полный путь:

[target.aarch64-linux-android]
linker = "C:\\Users\\taimoor\\AppData\\Local\\Android\\Sdk\\ndk-bundle\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\aarch64-linux-android21-clang++.cmd"

Обратите внимание на .cmd в конце сборки Windows.

Если вы используете Mac OS с NDK v25, вы можете столкнуться с проблемой. Если это так — попробуйте предыдущие версии NDK.

Использование Gradle для автоматизации сборки

Gradle можно использовать для автоматического запуска сборки cargo всякий раз, когда мы хотим протестировать приложение. Это приведет к тому, что изменения, которые мы сделали на стороне Rust, будут автоматически обновлены в нашем приложении.

Обратите внимание, что это файл Gradle уровня приложения или модуля, а не файл Gradle уровня проекта. Добавьте строки с 20 по 27 и строку 65 и далее. Строка 65 и далее просто указывает Gradle запускать сборку cargo всякий раз, когда мы запускаем приложение. После запуска команды сборки cargo мы копируем созданные java-файлы и файл динамической библиотеки (.so) и вставляем их в каталог, который может быть прочитан Android и использован в нашем коде Kotlin.

Теперь приложение должно работать 😄.

Бонус: ведение логов

Давайте быстро реализуем ведение журнала, чтобы облегчить отладку нашего кода на Rust. В файл lib.rs добавьте следующее содержимое:

Мы используем крейт android_logger для создания журналов, а затем вызываем log_panics::init(), чтобы перенаправить все паники для регистрации, а не для вывода стандартной ошибки. Обратите внимание на атрибут #[generate_interface]. Это сообщает rifgen, что мы будем вызывать эту функцию из Kotlin, поэтому он должен добавить этот вызов метода в файл интерфейса.

Загрузка библиотеки из Kotlin

Теперь, когда мы настроили сторону Rust, давайте перейдем к стороне Kotlin. Теперь мы загрузим библиотеку из синглтона:

Добавьте различный импорт для созданного нами класса Logs. Обратите внимание, хотя мы и назвали функцию initialise_logging, мы можем использовать ее как initialiseLogging. Это потому, что мы указали CamelCase при настройке rifgen.

Запустите программу, чтобы увидеть информацию из логов кода Rust.

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Advertisement

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: