最近一直在研究 Android NDK 编程。把过程记录下来。以帮忙巩固学习。
一 NDK 简介
NDK全称:Native Development Kit
官方网址:http://developer.android.com/tools/sdk/ndk/index.html
The NDK is a toolset that allows you to implement parts of your app using native-code languages such as C and C++. For certain types of apps, this can be helpful so you can reuse existing code libraries written in these languages, but most apps do not need the Android NDK.
Before downloading the NDK, you should understand that the NDK will not benefit most apps. As a developer, you need to balance its benefits against its drawbacks. Notably, using native code on Android generally does not result in a noticable performance improvement, but it always increases your app complexity. In general, you should only use the NDK if it is essential to your app—never because you simply prefer to program in C/C++.
Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need.
二 环境打建
1) 文件准备
网上关于环境搭建的文章很多。看了一些,好多讲的是以前版本的NDK搭建很多。方法也很麻烦。其实,只使用新版本NDK就够了。从官网下载对应版本的开发包,解压到某个目录。比如我们下载的android-ndk-r9c。
2) 配置环境变量。
如果你使用的是Linux. 将你解压的目录添加进系统环境变量.方法:将这些信息
export ANDROID_NDK_BUILD=/(你的目录)/android-ndk-r9c
export PATH=$PATH:$ANDROID_NDK_BUILD
写入~/.bashrd .然后 source ~./bashrc
一切OK.
如果你使用的是Windows 将你解压的目录添加进系统环境变量。.方法:在桌面,右击计算机-->属性--> 高级系统设置--环境变量-->找到PATH在前面添加你下载的NDK解压后的根目录例如:F:\android-ndk-r8d;。点击保存
一切OK
三。 开发步骤
1. 创建正常的Android工程
2. 编写声明native方法的java类
public class PrintHello {
static{
System.loadLibrary("hello-jni");
}
public PrintHello() {
// TODO Auto-generated constructor stub
}
public native String printHello();
}
我们使用NDK编写的代码 最终都会编译成.so库文件。上面的static 代码块的作用就是将我们编译出的库文件加载进来。我们选择在加载类的时候 记载我们的so 文件。但这不是必须的。我们可以在我们使用里面的方法前的任何地方加载。其中, System.loadLibrary("hello-jni"); 里面的库文件名 我们可以指定。
3. 编译java类
4. 实现
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_jnilearn_PrintHello */
#ifndef _Included_com_example_jnilearn_PrintHello
#define _Included_com_example_jnilearn_PrintHello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_jnilearn_PrintHello
* Method: printHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_jnilearn_PrintHello_printHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
#include<stdio.h>
#include <stdlib.h>
#include "com_example_jnilearn_PrintHello.h"
/*
* Class: com_example_jnilearn_PrintHello
* Method: printHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_jnilearn_PrintHello_printHello
(JNIEnv *env, jobject object){
return (*env)->NewStringUTF(env, "Hello from JNI ! ");
}
接着 编写Android.mk 文件 熟悉linux编程的同学对makefile肯定都比教熟悉了。内容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := com_example_jnilearn_PrintHello.c
include $(BUILD_SHARED_LIBRARY)
其中:
LOCAL_MODULE := hello-jni 中的hello-jni 就是我们指定的编译的库文件的名称。(最后生成的文件名字是libhello-jni.so 在我们指定的名称前添加lib)
LOCAL_SRC_FILES := com_example_jnilearn_PrintHello.c 指定我们编译的源文件
include $(BUILD_SHARED_LIBRARY) 指定我们最终生成共享库
最后,我们修改 MainActivity的onCreate方法。添加
PrintHello hello = new PrintHello();
setTitle(hello.printHello());
好了一切都编写好了。
进入工程根目录。执行 ndk-build
如果出现
[armeabi] Compile thumb : hello-jni <= com_example_jnilearn_PrintHello.c
[armeabi] SharedLibrary : libhello-jni.so
[armeabi] Install : libhello-jni.so => libs/armeabi/libhello-jni.so
说明一切OK 。如果没有请确认环境变量是否设置正确。
运行工程 发现标题栏已经变成Hello from JNI ! 。