当前位置: 首页 > 科技观察

8步教你打开AndroidNDK入门教程的大门

时间:2023-03-17 18:56:41 科技观察

不久前,我们向大家介绍了如何在MyEclipse8.6上搭建Android开发环境。本文为外文翻译。我们将介绍如何学习安装AndroidNDK并开始使用它。在本教程结束时,您将创建自己的项目,这些项目只需从Java代码调用本机C代码。推荐主题:Android开发与应用详细教程详情技术:AndroidSDK、NDK、C语言难度:高级预计完成时间:60-90分钟前提经验在开始之前,我们需要花一些时间来了解本教程的难点。它被标记为“高级”。它被标记为“高级”,因为我们的作者希望确保您满足以下要求:您具有Java和C语言经验。可以适应命令行操作。您知道如何找出您的Cygwin、awk和其他工具的版本。可以适应Android开发。您有一个工作的Android开发环境(在撰写本文时我使用的是Android2.2)并且您使用Eclipse或者可以轻松地使Eclipse步骤适应您自己的IDE。即使你不满足这些条件,当然也欢迎你阅读本教程,但你可能会在某些步骤中遇到困难,如果你满足上述条件,这些问题将很容易解决。也就是说,即使您认为自己是移动开发的老手,在使用NDK时仍然很容易遇到困难和麻烦。请注意,您可能必须自己进行故障排除才能使开发系统上的一切正常运行。本教程提供示例项目的完整开源代码下载。关于何时使用NDK的注意事项如果您正在阅读本教程,您可能已经在考虑在您的Android项目中使用NDK。但是,我们想花点时间讨论一下NDK为何重要、何时使用它以及(同样重要)何时不使用它。一般来说,如果您的应用程序真的是处理器杀手,您只需要使用NDK。也就是说,你设计的算法应该利用DalvikVM中所有的处理器资源,原生运行更有利。另外,不要忘记在Android2.2中,JIT编译器会提高类似代码的效率。使用NDK的另一个原因是可移植性。如果你现有的应用程序中有大量的C语言代码,那么使用NDK不仅可以加快你项目的开发进程,还可以让你的Android和非Android项目中的修改保持同步。对于为其他平台编写的OpenGLES应用程序尤其如此。不要认为只使用本机代码就能提高应用程序的效率。在Java和本机C之间进行转换会增加一些资源开销,因此只有在您有一些处理器密集型任务时才真正需要这样做。第0步:下载工具好了,让我们开始吧。您需要下载NDK。我们首先开始下载,因为在下载过程中您可以检查以确保您需要的其余工具是正确的版本。从Android网站下载适用于您的操作系统的NDK。现在,检查您的工具版本:如果在Windows下,Cygwin1.7或更高版本将awk升级到***版本(我们使用的是20070501)GNUMake3.81或更高版本(我们使用的是3.81)如果其中任何一个太旧,请先升级进行中。第1步:安装NDK现在NDK已经下载(对吧?),您需要解压缩它。解压后放入合适的目录。我们把它和AndroidSDK放在同一个目录下。记住你把它放在哪里。现在,您可能想要将NDK工具添加到您的路径设置中。如果您使用的是Mac或Linux,则可以使用本机路径设置来完成。如果您在Windows下使用Cygwin,则需要设置Cygwin的路径设置。第2步:创建项目创建一个常规的Android项目。为避免以后出现问题,您的项目路径不得包含空格。我们的项目有一个名为“com.mamlambo.sample.ndk1”的包和一个名为“AndroidNDK1SampleActivity”的默认活动-您稍后会看到它们。在项目的顶层创建一个名为“jni”的目录——这是您放置本机代码的地方。如果你熟悉JNI,那么你就会知道,AndroidNDK很大程度上是基于JNI的概念——它本质上是一个JNI,带有有限的C语言编译头文件。第3步:添加一些C代码现在,在jni文件夹中,创建一个名为native.c的文件。最初将以下C代码写入文件,稍后我们将添加另一个函数:env,logThis,&isCopy);__android_log_print(ANDROID_LOG_DEBUG,DEBUG_TAG,"NDK:LC:[%s]",szLogThis);(*env)->ReleaseStringUTFChars(env,logThis,szLogThis);}这个函数实际上很浅。它采用Java对象字符串参数,将其转换为C字符串,并将其写入LogCat。但是函数的名称很重要。它遵循以“Java”开头的特定模式,然后是包名,然后是类名,然后是方法名,如Java中所定义的那样。每个部分由下划线而不是点分隔。这个函数的前两个参数也很重要。第一个参数是JNI环境,它和辅助函数将被频繁调用。第二个参数是函数所属的Java对象。第4步:从Java调用本机代码现在您已经编写了本机代码,让我们回到Java端。在默认的Activity中,根据自己的喜好创建一个按钮,并添加一个按钮处理程序。从按钮处理程序调用helloLog:helloLog("ThiswilllogtoLogCatviathenativecall.");然后你必须在Java端添加函数声明。将以下语句添加到您的Activity类:privatevoidhelloLog(StringlogThis);它告诉编译和链接系统这个方法将在本机代码中实现。***,你需要加载本机代码最终编译成的库。在Activity类中添加以下静态初始化器以按名称加载库(库的名称由您决定,将在下一步中使用):static{System.loadLibrary("ndk1");}Step5:Addnativecodejni文件夹下的Make文件,现在需要添加编译时要用到的makefile。该文件必须命名为“Android.mk”。如果你之前命名的文件是native.c,库是ndk1,那么Android.mk的内容应该是这样的:LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_LDLIBS:=-llogLOCAL_MODULE:=ndk1LOCAL_SRC_FILES:=native.cinclude$(BUILD_SHARED_LIBRARY)#p#第6步:编译本机代码现在您的本机代码已完成且make文件已准备就绪,是时候编译本机代码了。从命令行(Cygwin下的Windows用户),您需要在项目的根目录中运行ndk-build命令。ndk-build工具位于NDK工具目录中。将它添加到我们的路径是最方便的方法。在后续构建中,如果您使用“ndk-buildclean”命令,那么您可以确保重新编译所有内容。第7步:运行代码现在您可以运行代码了。在您最喜欢的模拟器或手持设备中加载项目,查看LogCat,然后单击按钮。可能会发生两件事。首先,它可能工作正常。在这种情况下,恭喜!你可能想继续阅读。您还可能会在LogCat中收到诸如“无法执行活动方法”之类的错误。这个是正常的。这只是意味着你错过了一步。这在Eclipse中很容易发生。通常,Eclipse设置为自动重新编译。如果它不知道某些内容已被修改,它不会自动重新编译和重新链接。在这种情况下,Eclipse不知道您编译了本机代码。因此,“清理”项目(在Eclipse工具栏中单击“项目”->“清理”)会强制Eclipse重新编译。第8步:添加另一个本机函数下一个函数将演示的不仅是返回值的能力,还有返回字符串等对象的能力。在native.c中添加如下函数:jstringJava_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_getString(JNIEnv*env,jobjectthis,jintvalue1,jintvalue2){char*szFormat="Thesumoftwonumbersis:%i";char*szResult;//addthetwovaluesjlong??sum=value1+value2;(sizeof(szFormat)+20);//standardsprintfsprintf(szResult,szFormat,sum);//getanobjectstringjstringresult=(*env)->NewStringUTF(env,szResult);//cleanupfree(szResult);returnresult;}用于正常编译,您将需要添加inclustdio.h声明。此外,为了响应这个新的原生函数,请在您的ActivityJava类中添加以下语句:privateStringgetString(intvalue1,intvalue2);您现在可以随意设置其功能。我们使用以下两个调用和输出:Stringresult=getString(5,2);Log.v(DEBUG_TAG,"Result:"+result);result=getString(105,1232);Log.v(DEBUG_TAG,"Result2:“+结果);回到C函数,您会注意到我们已经做了很多事情。首先,我们需要在malloc()函数中使用sprintf()调用时创建一个缓冲区。如果您没有忘记使用free()函数清理结果,这是有道理的。然后,要返回结果,您可以使用名为NewStringUTF()的JNIhelper函数。这个函数基本上接受一个C字符串并使用它来创建一个新的Java对象。然后可以将这个新的String对象作为结果返回,您可以将它用作Java类中的常规JavaString对象。指令集、兼容性等。AndroidNDK需要AndroidSDK1.5或更高版本。在较新版本的NDK中,一些新的头文件可用于扩展对某些API的访问——尤其是OpenGLES库。不过,这些不是我们正在谈论的兼容性。这是本机代码,在使用时由处理器架构编译。因此,您必须问自己的一个问题是它支持哪种处理器架构?在当前的NDK(撰写本文时)中,它仅支持ARMv5TE和ARMv7-A指令集。默认情况下,目标架构设置为ARMv5TE,可以在使用ARM芯片的Android设备上运行。它预计将来会支持其他指令集(提到x86)。这里有一个有趣的潜在情况:NDK解决方案并非适用于所有设备。例如,市场上有使用x86指令集的英特尔(Intel)凌动处理器的Android平板设备。那么模拟器上的NDK呢?模拟器运行一个真正的虚拟机,包括完整的处理器虚拟化。是的,这意味着在虚拟机中运行Java就相当于在虚拟机中运行虚拟机。你会如何总结你的结果?您是否安装了AndroidNDK并最终得到了一个部分用本机C代码编写的功能齐全的工作应用程序?我们希望如此。有很多潜在的“出了点问题!”一路上的可能性,但在某些方面是值得的。一如既往,欢迎评论。原标题:AdvancedAndroid:GettingStartedwiththeNDK来源:http://mobile.tutsplus.com/tutorials/android/ndk-tutorial/原作者:ShaneConder&LaurenDarcey【编辑推荐】《AndroidUI》设计详解,多图官方教程基于MyEclipse8.6Android开发环境Android开发必备的21款免费资源和工具Android开发:自由选择TextView的文本Android开发:如何实现TCP和UDP传输