本文来自:安卓航班网
教程细节
技术:Android SDK、NDK、C 语言
难度:进阶
预计完成时间:60-90 分钟(⊙﹏⊙b汗,还是挺长时间的)
先决经验:
在开始之前,需要先花点时间了解一下这一教程的难度。它的标记是“进阶”。之所以标为“进阶”是因为作者想要确保你符合以下要求:
1、有Java和C语言经验。
2、能适应命令行操作。
3、知道如何了解你的 Cygwin、awk 和其他工具的版本。
4、能适应 Android Development。
5、有一个有效的 Android 开发环境(本文撰写时,笔者使用的是 Android 2.2)
5、使用 Eclipse 或者可以将 Eclipse 的指导步骤轻松应用于自己的 IDE 上。
6、就算并不满足这些条件,当然也欢迎你阅读这一教程,不过可能在某些步骤遇到困难。
如果满足了以上条件这些困难就会轻易解除。也就是说,即使认为自己是个移动开发老手,使用 NDK 依然很容易碰到困难和麻烦。请注意可能要自行排查故障才能让一切正常运转于你的开发系统中。
本教程提供完整的样例项目的开源代码。(我么有找到下载的东东)
何时使用 NDK 的说明
好,正在阅读这篇教程的你,也许已经在考虑在你的 Android 项目中使用 NDK 了。不过,作者想要花点时间讨论一下 NDK 为什么那么重要、何时该使用它,以及——同等重要的,何时不该使用它。
总的来说,只有当应用程序真的是个处理器杀手的时候,你才需要使用 NDK。也就是说,你设计的算法要利用 DalvikVM 中所有的处理器资源,而且原生运行较为有利。还有,别忘了在 Android 2.2 中,JIT 编译器会提高类似代码的效率。
另一个使用 NDK 的原因是方便移植。如果在现有的应用程序中有大量的 C 语言代码,那么使用 NDK 不仅可以加速你项目的开发进程,也能在你的 Android 和非 Android 项目中保持修改的同步。这一点对于那些为其他平台而写的 OpenGL ES 应用程序来说尤为如此。
别以为只要用了原生代码就能提高应用程序的效率。Java 与原生C 语言之间的转换会增加一些资源开销,因此只有你有一些集中消耗处理器资源的任务时才真正有必要这么做。
第 0 步:下载工具
好了,现在就开始吧!你需要下载 NDK。先来开始下载,因为在下载的过程中你可以检查一下,确保所需要用到的其余工具的版本都正确。
从 Android 网站下载适合你的操作系统的 NDK。
现在,对照下列检查你的工具版本:
1、如果在 Windows 下,Cygwin 1.7 或更高版本
2、将 awk 升级到最新版本(我们使用的是 20070501)
3、GNU Make 3.81 或更高版本(我们使用的是 3.81)
如果其中任何一个的版本太旧,请在继续之前先升级。
第 1 步:安装 NDK
既然 NDK 已经下载完成(没错吧?),你就需要解压缩它。解压后将它放入合适的目录中。要把它放在和 Android SDK 相同的目录下。记住你把它放在哪里了。
现在,你也许想要在路径设置中添加 NDK 工具。如果你在 Mac 或 Linux 下,你可以用你的原生路径设置来完成。如果你在 Windows 下的 Cygwin,你就需要设置 Cygwin 的路径设置。
第 2 步:创建项目
创建一个常规的 Android 项目。为了避免日后的问题,你项目的路径必须不包含空格。作者的项目有个叫做“com.mamlambo.sample.ndk1”的包,带有一个叫做“AndroidNDK1SampleActivity”的默认 Activity——你之后还会看到它们。
在这个项目的顶层创建一个叫做“jni”的目录——这是你放置原生代码的地方。如果你很熟悉 JNI,那你就会知道 Android NDK 很大程度上基于 JNI 的概念——它本质上是个只有有限的 C 语言编译头文件的 JNI。
第 3 步:添加一些 C 语言代码
现在,在 jni 文件夹中,创建一个叫做 native.c 的文件。一开始将以下 C 语言代码写入该文件,我们以后再添加另一个函数:
#include
#include
#include
#define DEBUG_TAG "NDK_AndroidNDK1SampleActivity"
void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv * env, jobject this, jstring logThis)
{
jboolean isCopy;
const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);
(*env)->ReleaseStringUTFChars(env, logThis, szLogThis);
}
这个函数实际上非常浅显。它获取一个 Java 对象的字符串参数,将它转换为 C-string,然后将它写入到 LogCat 中。
不过该函数的名字很重要。它遵循了以“Java”的特定字样开头,后面跟着包名称,然后类名称,然后方法名称,和 Java 中定义的一样。每一部分都由一根下划线隔开,而不是点。
该函数的头两个参数也很重要。第一个参数是 JNI 环境,它与 helper 函数会被频繁调用。第二个参数是该函数所属的Java 对象
第 4 步:从 Java 中调用原生代码
既然你已经写好了原生代码,让我们回头看看 Java 这边。在默认的 Activity 中,按照你的喜好创建一个按钮,并添加一个按钮处理器。从按钮处理器中,对 helloLog 作调用:
helloLog("This will log to LogCat via the native call.");
private native void helloLog(String logThis);
最后,你需要加载原生代码最终编译到的库。在 Activity 类中添加如下的静态初始化程序来根据名称加载库(库的名字随你决定,在下一步还会用到):
static {
System.loadLibrary("ndk1");
}
第 5 步:添加原生代码的 Make 文件
在 jni 文件夹中,现在你需要添加在编译中要用到的 makefile。该文件必须以“Android.mk”命名,如果你之前命名的文件为 native.c,库为 ndk1,那么 Android.mk 的内容就应该是这样:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1
LOCAL_SRC_FILES := native.c
include $(BUILD_SHARED_LIBRARY)
原文地址:http://www.apkway.com/forum.php?mod=viewthread&tid=20&extra=page%3D2