Step by Step搭建Android NDK开发环境2011-02-13 23:04:28| 分类: Android | 标签:android ndk |字号大

小 订阅
原文:http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/
作者:Ivan

译者:玄机逸士



大多数Android开发者是从纯Java、基于Android SDK应用开始学习Android编程的,而且每个人都知道,他们无须使用NDK(Native Development Kit)。由于NDK及其文档和示例,均独立于SDK,因此,如果在开发中不用它实际操练一次,就不大可能熟悉它。

因为这样的原因,很多人认为NDK是Android开发中的“巫术(black magic)”,许多不熟悉NDK的开发者,认为1) NDK复杂难懂,难以使用。与此同时,也有许多开发者认为NDK是一种万灵药(silver bullet),能解决SDK所不能解决的一切问题。

事实上,正如我将在这篇文章中说明的那样,这两种观点都是相当错误的。尽管的确带来了维护成本,也确实给项目增加了技术方面的复杂度,但安装NDK或者在项目中使用NDK并不困难。同时,在某些情况下,NDK的确能给应用程序带来很大的帮助。NDK提供的API比较有限,这些API主要用于几个和性能相关的领域,比如:

l OpenGL,包括支持(Java)SDK所支持的一些新版本

l Math,(一些,但非全部的,专门针对计算的算法。在native层面实现可获得更好的性能)

l 2D graphics, 从2.2开始支持像素缓冲(pixelbuffer)

l libc,提供了兼容性支持,并可能为移植现有native代码提供方便



在本教程中,我们将在前一篇文章中谈及的建立基本Android开发环境的基础上,增加NDK支持。我们也会用NDK创建一个项目的基本框架,以资各位开发NDK应用借鉴。

配置开发环境所必须的软件下载,需要一些时间(30分钟左右),所以请准备好。

准备好了吗?Let’s go!



Step1: 在Eclipse中增加C/C++支持

在前一个教程,我们安装了最基本的Eclipse,以及让Eclipse支持Android开发的Android SDK和ADT。


NDK同时支持C和C++,但C++的支持相对要弱一些,比如,不支持异常,以及在调用静态构造函数和静态析构函数时,存在一些bug。大多数情况下,使用NDK的目的,就是把和性能相关的代码,移到本地(native)层面去实现,你不大可能需要过多的OOP抽象以及其设计方面的优势(译者注:OOP往往会用到虚函数,而这会降低程序运行的性能。设计模式更是如此,通常,设计模式在带来代码的可维护性和可扩展性优势的同时,几乎无可避免地带来性能方面的损害)。我想说的就是,NDK的代码更倾向于用C编写,而不是C++。
不管怎么说,我们的Eclipse安装到目前为止既不支持C也不支持C++。我们实际上也不需要完整的支持,包括诸如编译、连接之类的事情。但是,我们希望Eclipse能够让C/C++的关键字显示为不同的颜色,以及进行基本的语法检查。这就要求我们通过Eclipse更新机制,为其增加这方面的特性,就像我们让Eclipse增加支持Android特性那样。

现在,进入Help – Install New Software菜单项,选择Galileo作为更新站点(“Work with”)。等待更新项目树加载,然后选中Programming Languages分支下的Eclipse C/C++ Development Tools:


然后点击Next按钮。按照后续的提示,接受缺省的选项,最后必须接受许可,以便让Eclipse完成更新。完成后,你将会看到要求重启Eclipse的提示:



点击Yes按钮,等待Eclipse重启。现在你的Eclipse就支持C/C++了。



Step2: 安装Cygwin

Android是基于Linux的,因此如果你要为它编写native代码,你就需要一些Unix工具。在Windows上,NDK支持Cygwin1.7.x或者更高的版本。Cygwin是什么?它只不过是在Windows上,模拟提供Unix环境的一系列的工具而已,这在有些时候很必要的,就像我们现在的情况。

到www.cygwin.com下载Cygwin:



在右边有一个灰色的小图标“Install or update Cygwin now!”,点击它,Cygwin的setup.exe就会被下载下来,并开始运行。



选中Install from Internet,点击Next按钮,然后选择安装路径(注意:安装路径中不能包含空格字符) – 当然这需要一些硬盘空间。然后在选择本地包路径 – 随便选择一个临时的目录就可以了,因为以后基本上不会用到它。

到这里,Cygwin会首先连接到中心网站,并下载镜像网站列表。选择一个地理上看起来较近的站点,这有可能会节省一些下载的时间(译者注:在国内访问国外的网站,访问速度其实和地理位置的远近没有必然的联系,比如访问日本的网站,往往比访问美国的网站更慢,尽管日本在地理上离我们更近。因此,建议在下载之前,用ping命令看看网站列表中,访问哪个网站需要的时间最少)。


选定镜像网站后,点击Next按钮,Cygwin就会下载,并向你展示可下载软件包的列表:



缺省地,只有base包会被安装。我们则需要Devel包。不要去挑选我们需要什么样的包,因为这样有可能会导致包之间的依赖性丧失或者其他典型的Unix梦魇,所以,我建议安装整个Devel分支。分几次单击Devel根节点边上的“Default”,直到“Default”变成“Install”,就像上图所示的那样。

现在点击Next按钮,Cygwin就会下载选中的软件包并着手安装:


这一步需要一些时间,所以你不妨去喝一杯咖啡,如果网速确实比较慢的话,去享用你的午餐也没有什么问题。

当你回来后,你可能就可以看到安装的最后一步:


允许它在桌面创建图标。点击Finish按钮后,你就会看到桌面上出现了一个Cygwin图标,它就是用来启动Cygwin控制台的:



试一试,让Cygwin控制台启动并初始化:


在控制台中输入make –v命令,来检查Android NDK所必须的工具是否已经存在:


你应该可以看到同样的输出,它告诉我们GNU Make工具已经在由Cygwin模拟的Unix环境中存在。Cool!

注意:根据我的经验,Cygwin安装通常不太稳定,而且经常会出错。如果你有什么这方面的问题,咱们可以在留言中讨论,我会尽量帮忙。在这一步,如果有什么错误,就没有必要继续下去了(译者注:言下之意,需要重新来过),因为在Windows上进行NDK开发,正确安装Cygwin是必须的。



Step3: 安装Android NDK

下一步就是下载Android NDK,并把它放到我们的文件系统中。NDK可以从Android官方网站获得。



下载Windows平台上的NDK zip包,并将其解压到某个目录,再次注意,目录中不能有空格字符。我将它解压到C:\,所以目录路径就是C:\android-ndk-r4。

现在,开发我们的第一个NDK应用的环境就准备好了!



Step4: Making一个基本的NDK应用

在应用中,使用NDK的基本思路就是,将本地代码(native code)编译成函数库,然后就可以在Java代码中使用它。因此,你总会从创建一个标准的(Java)应用开始,再将NDK片段加入。现在就像咱们前面做的那样,用New Android Project Wizard,先在Eclipse中创建一个基本的应用:



不管你相信与否,必须再次确信路径中没有空格字符。我的Eclipse工作区在一个带有空格字符的目录里面,所以,正如上图所示,我不得不取消Use default location复选框,手动地选择一个没有空格字符的路径。总之,Eclipse工作区最好存在于没有空格字符的路径里面。

否则,在创建项目的时候,你无法处理和NDK相关的事情。我让Winzard创建缺省的NdkFooActivity,这个Activity我们后面将会用到。

用Wizard创建好应用后……



在项目的根节点创建一个文件夹jni(右键单击项目节点,New - Folder)。在这个新创建的文件夹里面,新建一个文件Android.mk(New - File),使其内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Here we give our module name and source file(s)

LOCAL_MODULE := ndkfoo

LOCAL_SRC_FILES := ndkfoo.c

include $(BUILD_SHARED_LIBRARY)

除去模块名(ndkfoo)外,文件中其它东西都不用关心。当然如果愿意,你自己可以对Unix的Makefile的写法进行深入研究。

对NDK的build过程来说,Android.mk至关重要,它用来区分NDK模块。在我们这个例子中,模块的名字是ndkfoo,它告诉build工具它包含了一个源文件ndkfoo.c。我们到jni文件夹里创建ndkfoo.c:



下面的就是这个文件的内容:

#include <string.h>

#include <jni.h>



jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis)

{

return (*env)->NewStringUTF(env, "Hello from native code!");

}

Android实际上通过JNI(Java Native Interface),用标准的Java方式和本地(native)代码通讯。它定义了Java代码和C/C++代码之间彼此互动的规范和机制。你可以从Sun官方文档中,更多地了解JNI,不过现在你或许注意到了上面C函数的名称并不是随便给出的 – 它对应的是Java中的类名。进一步地,该函数用JNIEnv对象创建一个Java 字符串,并将其返回给调用者。

如果在很多地方需要使用NDK,那么你应该多了解一些JNI。顺便提一下,在本地代码中调用Java方法,创建一些自定义的对象等等,也是可以的。

现在,为了用上面写的C代码创建二进制库,我们需要用到Cygwin和Android NDK工具。启动Cygwin控制台,用cd命令进入到项目所在的文件夹。注意,Windows驱动器已被映射到你目前正在工作的,模拟Unix环境的/cygdrive目录下。在我的机器上,命令就是:cd /cygdrive/c/projects/ndkfoo。

然后,发出调用NDK build工具的命令。在我的机器上,因为NDK安装在C:\,所以命令看起来像这样:
/cygdrive/c/android-ndk-r4/ndk-build,如下图所示:



正如你可能注意到的,ndk-build成功运行后,将会在项目根节点下创建一个叫libs的新文件夹,并在其中创建一个.so文件。这个.so文件就是二进制库,它将被包含到应用的.apk包中,并可以被Java代码链接。在Eclipse中,你只需要在选中项目根节点后,按F5键,就可以将在Cygwin控制台中所做的更改,更新到Eclipse项目中。

如果修改了NDK代码中的C/C++源文件,那么就必须重新运行ndk-build命令。由于Eclipse ADT不支持NDK,所以你需要在Cygwin控制台中去做这件事情。每次都不能忘记更新Eclipse项目!
不管怎么说,NDK部分的工作到这里就做完了。现在我们要做的就是修改NdkFooActivity这个类的Java代码:

package com.mindtherobot.samples.ndkfoo;



import android.app.Activity;

import android.app.AlertDialog;

import android.os.Bundle;



public class NdkFooActivity extends Activity

{

// 加载库 – 名字必须匹配jni/Android.mk

static

{

System.loadLibrary("ndkfoo");

}



// 声明本地代码函数 – 必须匹配ndkfoo.c

private native String invokeNativeFunction();



@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);



// 这里调用本地代码

String hello = invokeNativeFunction();


new AlertDialog.Builder(this).setMessage(hello).show();
}

}

正如你可能猜到的那样,上面的代码调用了NDK中返回字符串的那个方法,返回的字符串将作为一个警告信息显示在屏幕上。下图就是ndkfoo应用在模拟器上的运行结果:






Step5: 明智和小心

如前所言,也可能因为你现在更加了解了,NDK并非怪物,在应用中使用它还是相当容易的。尽管如此,每次使用NDK前,请你三思,并考虑使用它真正能带给你什么好处。从代码质量的角度来看,将C/C++和Java代码混起来,通常并不是一个好主意,同时Dalvik VM也正在变得越来越快,所以在很多情况下,你可以避免使用NDK。

再次提醒,为了确保正确和安全地使用NDK,一定要阅读NDK的文档和彻底地学习JNI。

http://patmusing.blog.163.com/blog/static/135834960201111311022896/

更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. Android(安卓)Studio 3.0 Canary 8无法安装apk到小米手机
  3. android中webview开启了硬件加速后会出现闪烁问题
  4. Android(安卓)和 PHP 之间进行数据加密传输
  5. Lottie-移动动画效果框架
  6. android上传图片到服务器,求服务器那边和android的Activity的完整
  7. 最新eclipse中android插件安装下载地址
  8. android实用代码
  9. linux下android开发环境的配置

随机推荐

  1. 基于PHP聊天室的编程思想
  2. 检查PHP是否启用了JavaScript
  3. php计算几分钟前、几小时前、几天前的几
  4. jQuery ajax调用不会调用我的php页面
  5. 复制到剪贴板没有瑞士法郎。只使用javasc
  6. 使用codeigniter发布到wordpress.com博客
  7. 用简单的馅饼从原子进料中拉出
  8. php curl模拟登陆抓取数据
  9. php 自己做的简单论坛
  10. fgetcsv()错误地将双引号添加到第一行的第