Як почати використовувати код С ++ у своєму проекті Android

Минулого року я виступив з доповіддю на GDG DevFest в Анкарі, Туреччина. З тих пір я планую поділитися цією розмовою. Тепер, коли я кандидат в доктори наук і маю трохи більше часу, я розміщую цю посаду тут.

Якщо ви хочете отримати презентацію, вона доступна на моєму диску.

Розминка

Для початку я хотів би пояснити процес створення програми в Android. Оскільки вам потрібно знати деякі основні внутрішні речі, ця тема є дещо технічною.

Вам не потрібно знати все, що показано на зображенні вище, але це хороша довідка.

Тепер скажімо, що ви пишете програму для Android за допомогою Java. У вас буде:

  • вихідний код для цієї програми
  • якісь файли ресурсів (наприклад, зображення або файли xml для розташування графічного інтерфейсу)
  • і, можливо, деякі файли AIDL, які є інтерфейсами Java, що змушує процеси обмінюватися даними.

Ви, ймовірно, також збираєтеся використовувати додаткові бібліотеки та пов'язані з ними файли у своєму проекті.

Створюючи робочий додаток, ви спочатку компілюєте ці вихідні коди разом. Компілятор видасть файл DEX, який потім зможе прочитати віртуальна машина. Цей машиночитаний файл та деяка додаткова інформація про програму будуть упаковані разом менеджером пакетів. Остаточний пакет - званий пакет APK - є остаточним додатком.

Це процес створення пакета Android найпростішими словами.

Час роботи Android

Тепер поговоримо про час роботи. У вас є програма, і коли вона починає працювати, вона читається машиною. Android має два типи віртуальних машин для запуску програми. Я не буду представляти старий, який називається Dalvik, оскільки сьогодні на більшості пристроїв Android працює віртуальна машина під назвою Android Run Time, ART - отже, про це ми поговоримо тут.

ART - це випереджаюча віртуальна машина (AOT). Отже, що це означає? Дозволь пояснити. Коли ваш додаток запускається вперше, його код компілюється до машинного коду, який потім може прочитати справжня машина. Це означає, що код не компілюється по частинах під час виконання. Це збільшує час встановлення програми, одночасно зменшуючи споживання батареї.

Підсумовуючи, ви пишете програму, а потім компілюєте її у двійковий код, який читає ART. Потім ART перетворює цей код на власний код, який може прочитати сам пристрій.

ART & C ++

Що робити, якщо ви пишете додаток для Android за допомогою Java, але є якийсь код C ++, який контактує з Java? Який вплив цього коду C ++ на процес збірки або час роботи вашого додатка? Не надто багато.

Код С ++ компілюється безпосередньо до реального машинного коду його компілятором. Отже, якщо ви використовуєте код C ++, він буде упакований як машиночитаний код у вашому пакеті. ART не буде обробляти його, поки він перетворює ART-зчитуваний код у машино-зчитуваний код під час першого використання. Вам не потрібно турбуватися про цей процес. Ви відповідаєте лише за написання інтерфейсу, який дозволяє Java розмовляти з C ++. Про це ми скоро поговоримо.

Процес побудови C ++

Тепер ми повинні поговорити про процес побудови C ++. Вихідний код (файли .cpp та .h) на першому кроці перетворюється на розширений вихідний код препроцесором. Цей вихідний код містить велику кількість коду. Незважаючи на те, що ви можете отримати остаточний виконуваний файл за допомогою команди, подібної вище, можна вирізати кроки побудови за допомогою відповідних прапорів. Ви можете отримати розширене джерело, надавши прапорець -E компілятору g ++ . У мене є файл 40867 рядка для 4-рядкового вихідного коду.

Використовуйте g ++ -E hello.cpp -o hello.ii, щоб отримати розширений вихідний код.

Другий - це власне крок компіляції. Компілятор компілює наш код, щоб отримати файл асемблера. Отже, справжня компіляція дає файл асемблера, а не виконуваний файл. Цей файл збирається асемблером. Отриманий код називається об'єктним кодом. Коли у нас є кілька бібліотек, спрямованих на зв’язування одна з одною, ми маємо багато об’єктних кодів. Ці об'єктні коди пов'язані за допомогою лінкера. Тоді ми отримуємо виконуваний файл.

Існує два види зв'язування: динамічне та статичне.

Отже, настав час зайти трохи глибше, коли ми обговорюємо чисті речі на C ++.

Найголовніше: Ви можете розглядати статичні зв’язані бібліотеки як частину свого коду. Тож будьте обережні, коли прив’язуєте бібліотеку до свого проекту. Оскільки бібліотека, якою ви користуєтесь, може не мати відповідної ліцензії для статичного зв’язку. Більшість бібліотек з відкритим кодом обмежено для використання як динамічно пов’язаних.

З технічної точки зору, статично пов'язана бібліотека пов'язана з проектом під час побудови компілятором. З іншого боку, динамічно пов’язана бібліотека пов’язана операційною системою під час роботи. Тому вам не потрібно розповсюджувати свій проект із кодом бібліотеки, який ви використовуєте. Ви також можете використовувати бібліотеку іншого проекту або системну бібліотеку.

Через це динамічне зв’язування може спричинити уразливість у вашому проекті. Хоча справа безпеки виходить за рамки цієї публікації, проте.

Деякі поняття

CMake і Gradle

Якщо ми хочемо додати код C ++ в наш проект Android, добре використовувати CMake для обробки операцій збірки. Пам'ятаєте процес побудови, який я щойно представив вище? Коли у вас є купа бібліотек C ++ та вихідний код, ускладнюється обробка всіх них. Інструмент, такий як CMake, полегшує процес складання.

CMake буде доступний за замовчуванням, коли ви вирішите включити підтримку C ++ на початку проекту. Також вам потрібно використовувати закриття Gradle для того, щоб упакувати бібліотеки у ваш APK.

ABI

Як відомо, Android поширюється для різних пристроїв. Кожен пристрій може мати різну архітектуру процесора. Коли ви розробляєте програму для Android, яка містить код C ++, вам слід подбати про платформи, на яких ваша програма працюватиме.

Пам'ятаєте механізм побудови С ++, який я представив вище? Код С ++ слід компілювати як бібліотеку для кожної платформи, на яку ви націлюєтесь. Ви можете скомпілювати бібліотеку для всіх підтримуваних платформ, або ви можете скомпілювати її лише для однієї платформи.

Зверніть увагу, що 64-розрядна підтримка ABI буде обов’язковою під час випуску Android Pie, якщо ви хочете розмістити свій додаток у Google Play Store.

JNI

Це останнє, про що я хотів би познайомити вас щодо використання C ++ в Android. Як я вже згадував раніше, я представляю вам ці концепції, враховуючи, що ви хочете розробити програму за допомогою Java.

JNI - це абревіатура для Java Native Interface. Це дозволяє частинам C ++ та Java розмовляти між собою найпростішими термінами. Наприклад, якщо ви хочете викликати функцію з C ++ на Java, для цього слід написати інтерфейс JNI.

Вхідний lib.cpp є інтерфейсом, і він підключає код C ++ до коду Java. У наведеному вище прикладі єдиним кодом на C ++ є сам JNI. Однак ви можете включити бібліотеки, які ви хочете використовувати, і реалізувати функцію, яка їх викликає. Цю нову функцію можна викликати з частини Java. Тож це працює як міст таким чином.

Що робити, якщо ви хочете спробувати

Тут ви маєте всі необхідні та базові знання для використання C ++ у своєму проекті Android. Якщо ви хочете спробувати, ось як створити простий проект Android із кодом C ++.

На малюнках нижче показано кроки для початку такого проекту. Після їх закінчення, можливо, ви захочете прочитати цей пост, щоб змінити та глибше зрозуміти механізм.

Цей пост був лише вступом. Не забувайте, є ще багато речей, яким можна навчитися. Однак я мав на меті представити вам найважливіші речі щодо концепції використання С ++.