Интеграция Rust с Android-разработкой

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

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

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

Настройка 🌱

Плагин ржавчины ⚙️

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

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

Создание пустого приложения 📱

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

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

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

Включение грузового проекта 💼

Давайте теперь добавим Проект Cargo, следуя инструкциям, представленным здесь. Чтобы внедрить проект Rust, просто щелкните Терминал в Android Studio и введите cargo new rust_lib --lib, затем нажмите клавишу ввода.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вам может быть интересно, что происходит в build.rs. flapigen преобразует содержимое файла интерфейса в файл java_glue rust. Поэтому мы сначала указываем исходный файл для файла интерфейса (in_src), а затем выходной файл (java_glue.rs). Каталог java_glue.rs должен быть таким же, как и переменная OUT_DIR environment. После этого используйте rifgen для создания файла интерфейса, указав наши предпочтения в зависимости от языка, на который мы добавляем проект rust. Последний параметр Generator::new указывает начало папки, содержащей наш код ржавчины, а функция 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. Это соединит ваш код ржавчины с сгенерированным.

Добавьте наборы инструментов Android и компоновщики ⛓

Чтобы скомпилировать 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 build всякий раз, когда мы хотим протестировать приложение. Это приведет к тому, что изменения, которые мы сделали на стороне Rust, будут автоматически обновлены в нашем приложении.

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

Теперь приложение должно работать 😄. Если у вас возникли трудности с его запуском, оставьте комментарий ниже или напишите мне по адресу [email protected]!

Дополнительный раздел: Ведение журнала📃

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

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

Загрузка библиотеки из Котлина 📲

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

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

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

Следующие шаги 🍀

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

Рекомендации

Давайте свяжемся на Upwork, если вам нужна какая-либо помощь или если вам нужно больше рук для проекта, над которым вы работаете!

Я также редактирую изображения (ретушь, компостирование, улучшение изображений и т. д.), поэтому не стесняйтесь обращаться ко мне! 😄😄

Репозиторий