如何开始使用Android的本机开发套件

随着Android Studio 2.2的发布,开发包含C ++代码的Android应用程序比以往任何时候都更加容易。 在本教程中,我将向您展示如何使用通常称为NDK的Android Native Development Kit创建一个本机C ++库,其功能可用于Java类。

先决条件

为了能够遵循本教程,您将需要以下内容:

1.为什么要编写本机代码?

根据经验,您将仅使用Java开发Android应用程序。 添加C ++代码会大大增加其复杂性,并降低其可移植性。 不过,出于某些原因,您仍然想要这样做:

  • 最大化性能 :通过用C ++实现其业务逻辑中占用大量CPU的部分,您可以提高Android应用程序的性能,尽管只是略有提高。
  • 要使用高性能API :NDK中包括Vulkan GraphicsOpenSL ES之类的API规范的实现。 因此,Android游戏开发人员倾向于使用NDK。
  • 要使用流行的C / C ++库,请执行以下操作 :现有许多C和C ++库没有Java等效项。 如果您想在Android应用程序中使用它们,则可以使用NDK。
  • 重用代码 :只要不包含任何特定于平台的依赖项,用C ++编写的代码就可以在Android和iOS应用程序中使用,通常只需很少的更改即可。 如果您正在开发大型应用程序并打算同时支持iOS和Android平台,则使用C ++可能会提高您的生产率。

2.创建一个新项目

在Android Studio 2.2或更高版本中,项目创建向导可让您快速创建支持C ++代码的新项目。

首先启动Android Studio,然后在欢迎屏幕中按“ 启动新的Android Studio项目”按钮。 在下一个屏幕中,为您的应用程序指定一个有意义的名称,然后选中“ 包括C ++支持”字段。

项目配置画面

在向导的活动创建屏幕中,选择“不添加活动”选项。 在向导的最后一个屏幕中,确保“ C ++标准”字段的值设置为“ 默认工具链” ,然后按“ 完成”按钮。

工具链选择屏幕

默认情况下未安装Android NDK及其依赖的工具。 因此,生成项目后,您将看到如下错误:

没有发现NDK错误

要解决该错误,请转到工具> Android> SDK Manager,然后切换到“ SDK工具”标签。

在可用的开发人员工具列表中,选择CMakeNDK ,然后按“ 应用”按钮。

SDK工具对话框

安装完成后,重新启动Android Studio。

3.创建本地库

支持C ++的Android Studio项目还有一个名为cpp的附加源代码目录。 您可能已经猜到了,所有C ++文件和库都必须放在其中。 默认情况下,该目录具有一个名为native-lib.cpp的文件。 现在,我们将在其中编写所有C ++代码。

在本教程中,我们将创建一个简单的本机库,其中包含一个使用公式πr²计算圆的面积的函数 。 该函数将圆的半径作为jdouble ,并将面积作为jstring返回。

首先向文件添加以下include伪指令:

#include <jni.h>
#include <string>
#include <math.h>

jni.h是一个头文件,其中包含一些宏定义,类型,结构和函数,在使用NDK时,所有这些都是必不可少的。 (JNI表示Java本机接口,这是允许Java Runtime与本机代码进行通信的框架。) 字符串头文件是必需的,因为我们将在库中使用jstring类型。 math.h头文件包含π的值。

默认情况下,为了支持多态,C ++编译器会修改您在代码中定义的所有函数的名称。 此功能通常称为名称修改。 由于名称修饰,从Java代码调用C ++函数将导致错误。 为避免这些错误,您可以通过在extern "C"块内定义函数来禁用名称修饰。

extern "C" {
    // Your functions must be defined
    // here
}

可通过JNI访问的C ++函数的名称必须具有以下格式:

  • 它们必须具有Java_前缀。
  • 它们必须包含包装名称的错误形式,其中点用下划线替换。
  • 它们必须包含它们所属的Java类的名称。

此外,您必须指定功能的可见性。 您可以使用JNIEXPORT宏来实现。 按照惯例,大多数开发人员还将JNICALL宏包含在函数定义中,尽管它目前在Android中没有任何作用。

下面的代码定义了一个称为calculateArea的函数,可以从一个名为MainActivity的Java类访问该函数:

JNIEXPORT jstring JNICALL
Java_com_tutsplus_mynativeapplication_MainActivity_calculateArea(
        JNIEnv *jenv,
        jobject self,
        jdouble radius
) {

}

请注意,除了半径之外,该函数还接受JNIEnv类型(具有可用于处理Java类型的实用程序函数)和jobject实例,该实例是对MainActivity实例的引用。 当然,在本教程的后面,我们将创建MainActivity

计算面积很容易。 您需要做的就是将M_PI宏乘以radius的平方。

jdouble area = M_PI * radius * radius;

如此您就知道在使用JNI时如何处理字符串,现在让我们创建一个新字符串,其中包含一条消息,说明该区域是什么。 为此,您可以使用sprintf()函数。

char output[40];
sprintf(output, "The area is %f sqm", area);

因为Java无法直接处理C ++字符数组,所以函数的返回类型为jstring 。 要将output数组转换为jstring对象,必须使用NewStringUTF()函数。

return jenv->NewStringUTF(output);

至此,我们的C ++代码已准备就绪。

4.使用本机库

在上一步中,您看到了calculateArea()函数必须属于MainActivity Java类。 通过右键单击Java包名称并选择File> New> Empty Activity来开始创建类。

在弹出的对话框中,将活动命名为MainActivity 。 确保选中“ 启动器活动”选项后,按“ 完成”按钮。

创建一个新的启动器活动

必须先加载本机库,然后才能使用它。 因此,向该类添加一个static块,并使用System类的loadLibrary()方法加载该库。

static {
    System.loadLibrary("native-lib");
}

为了能够在活动中使用calculateArea() C ++函数,必须将其声明为本native方法。

private native String calculateArea(double radius);

现在,您可以像任何普通的Java方法一样使用calculateArea()方法。 例如,可以将以下代码添加到onCreate()方法中,以计算和打印半径为5.5的圆的面积:

Log.d(TAG, calculateArea(5.5f));

如果运行该应用程序,则应该能够在logcat窗口中看到以下输出:

在logcat中输出

结论

在本教程中,您学习了如何创建本机C ++库并在Android应用程序中使用它。 值得注意的是,默认情况下,本机生成过程会为NDK支持的每个CPU体系结构生成一个单独的.so文件。 因此,您可以确定自己的应用程序可以在大多数Android设备上运行,而不会出现任何问题。

要了解有关Android NDK的更多信息,建议您参考《 NDK指南》

翻译自: https://code.tutsplus.com/tutorials/how-to-get-started-with-androids-native-development-kit--cms-27605

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值