Android Studio с экспериментальным Gradle плагином и CrystaX NDK
14.12.2015 06:20

Ранее мы описали как использовать CrystaX NDK в Android Studio. С того времени Google анонсировал новый (экпериментальный) Gradle плагин с улучшенной поддержкой NDK в Android Studio. Давайте посмотрим, как использовать CrystaX NDK с этим новым плагином.

Будучи последовательными, мы обновим предыдущую статью, добавив в нее новые условия - т.е. это будет все то же простое UI приложение, использующее Boost.Serialization. Использование Boost необязательно для понимания новой схемы работы с экспериментальным Gradle плагином; тем не менее, мы включили пример работы с Boost для большей полноты примера.

В новом Gradle плагине Google отказался от использования старой, основанной на GNU Make, системы сборки (ndk-build). Теперь для описания каждого аспекта сборки используется Gradle DSL. Это хорошая новость для тех, кто не знаком со старым добрым GNU Make, и желает, чтобы весь процесс сборки целиком контролировался IDE, не заботясь о правке файлов для GNU Make.

Однако у этого подхода есть свои минусы. Наиболее важный - это необходимость разбираться в Gradle DSL и, само собой, уметь хотя бы немного программировать на Groovy.

Давайте посмотрим как это работает.

Java

Первым делом запустите Android Studio и создайте новый Android проект:

Выберите "Android 4.0.3" в качестве целевой версии Android:

Выберите "пустую" activity:

Оставьте все имена как есть и нажмите кнопку "Finish":

Gradle

По умолчанию, Android Studio все еще использует старый Gradle плагин. Давайте переключимся на новый (экспериментальный).

Для начала, откройте и отредактируйте несколько файлов:

build.gradle.diff

gradle/wrapper/gradle-wrapper.properties.diff

app/build.gradle.diff

Теперь нам надо открыть local.properties и добавить путь к CrystaX NDK:

sdk.dir=/opt/android/android-sdk-mac ndk.dir=/opt/android/crystax-ndk-10.3.1

Пользователям Windows: обратные слэши и двоеточия должны быть экранированы:

sdk.dir=C\:\\android\\android-sdk-mac ndk.dir=C\:\\android\\crystax-ndk-10.3.1

Теперь нужно синхронизировать изменения в gradle:

Layout

Теперь откройте файл app/res/layout/content_main.xml и поправьте его, чтоб он выглядел так:

content_main.xml.diff
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index ec3933f..077dacc 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -13,7 +13,9 @@ tools:showIn="@layout/activity_main"> <TextView + android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Hello World!" /> + /> + </RelativeLayout>
content_main.xml

MainActivity

Добавьте такие строки в MainActivity.onCreate():

TextView field = (TextView)findViewById(R.id.text); field.setText(getGPSCoordinates(getFilesDir().getAbsolutePath()));

Добавьте объявление нативного метода в класс MainActivity:

private native String getGPSCoordinates(String rootPath);

Также не забудьте добавить загрузку динамической библиотеки в статический блок инициализации:

static { System.loadLibrary("test-boost2"); }

Суммарные изменения:

MainActivity.java.diff
diff --git a/app/src/main/java/net/crystax/examples/testboost2/MainActivity.java b/app/src/main/java/net/crystax/examples/testboost2/MainActivity.java index f9c0821..0519122 100644 --- a/app/src/main/java/net/crystax/examples/testboost2/MainActivity.java +++ b/app/src/main/java/net/crystax/examples/testboost2/MainActivity.java @@ -8,9 +8,16 @@ import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; +import android.widget.TextView; public class MainActivity extends AppCompatActivity { + static { + System.loadLibrary("test-boost2"); + } + + private native String getGPSCoordinates(String rootPath); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -26,6 +33,9 @@ public class MainActivity extends AppCompatActivity { .setAction("Action", null).show(); } }); + + TextView field = (TextView) findViewById(R.id.text); + field.setText(getGPSCoordinates(getFilesDir().getAbsolutePath())); } @Override

В результате содержимое файла MainActivity.java должно стать таким:

MainActivity.java

Мы закончили заниматься Java-частью приложения; давайте теперь займемся кодом на C++.

C++

Первым делом включим нативную сборку в app/build.gradle:

app/build.gradle.diff

Теперь откроем MainActivity.java и добавим реализацию нативного метода:

Это создаст новый файл app/src/main/jni/test-boost2.c. Переименуем его в app/src/main/jni/test.cpp, а также добавим два новых файла: app/src/main/jni/gps.hpp и app/src/main/jni/gps.cpp.

app/src/main/jni/gps.hpp
app/src/main/jni/gps.cpp
app/src/main/jni/test.cpp

Наконец, добавим новые задачи и вспомогательные функции в app/build.gradle:

app/build.gradle.diff

Структура каталога

Файловое дерево каталога TestBoost2/app должно теперь выглядеть так:

. ├── app.iml ├── build.gradle ├── libs ├── proguard-rules.pro └── src ├── androidTest │   └── java │   └── net │   └── crystax │   └── examples │   └── testboost2 │   └── ApplicationTest.java ├── main │   ├── AndroidManifest.xml │   ├── java │   │   └── net │   │   └── crystax │   │   └── examples │   │   └── testboost2 │   │   └── MainActivity.java │   ├── jni │   │   ├── gps.cpp │   │   ├── gps.hpp │   │   └── test.cpp │   └── res │   ├── drawable │   ├── layout │   │   ├── activity_main.xml │   │   └── content_main.xml │   ├── menu │   │   └── menu_main.xml │   ├── mipmap-hdpi │   │   └── ic_launcher.png │   ├── mipmap-mdpi │   │   └── ic_launcher.png │   ├── mipmap-xhdpi │   │   └── ic_launcher.png │   ├── mipmap-xxhdpi │   │   └── ic_launcher.png │   ├── mipmap-xxxhdpi │   │   └── ic_launcher.png │   ├── values │   │   ├── colors.xml │   │   ├── dimens.xml │   │   ├── strings.xml │   │   └── styles.xml │   ├── values-v21 │   │   └── styles.xml │   └── values-w820dp │   └── dimens.xml └── test └── java └── net └── crystax └── examples └── testboost2 └── ExampleUnitTest.java

Конечный результат

Дело сделано! Теперь запустите сборку проекта как обычно (Build -> Make Module 'app') и стартуйте приложение на устройстве или эмуляторе. Ниже приводится снимок экрана с устройства при запущенном приложении:

Пример

Для простоты мы залили готовый к использованию проект на GitHub. Скачивайте и наслаждайтесь!

Back
Home
Map
Back
Home
Map

Наши авторы: