Android Studio 实验性 Gradle 插件与 CrystaX NDK 的配合使用
2015.12.14 06:20

之前我们介绍过如何在 Android Studio 中使用 CrystaX NDK 。 前些时候 Google 发布了一个 Android Studio 相关支持 NDK 开发的新(实验性)Gradle插件。 让我们来看看 如何基于这个新插件使用 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" 目标版本:

选择 空白 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()));

添加 native 方法的声明到 MainActivity 类:

private native String getGPSCoordinates(String rootPath);

同样的,别忘记在静态初始化部分添加 native 库的加载逻辑:

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 部分,现在切换到 native 部分。

Native 部分

首先我们在 app/build.gradle 中启用 native 编译:

app/build.gradle.diff

然后打开 MainActivity.java 添加 native 方法的实现:

它会创建 app/src/main/jni/test-boost2.c 文件。 现在把它重命名为 app/src/main/jni/test.cpp ,并添加另外两个文件: app/src/main/jni/gps.hppapp/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 Project) 并在设备上运行它。这里是运行结果的一个截屏:

示例项目

方便起见,我们上传了一份即时可用的项目到 GitHub 。 请随意签出查阅。

Back
Home
Map
Back
Home
Map

Our contributors: