最近因为项目的需要研究了一下NDK的使用,在测试NDK的时候也遇到一些问题,趁热打铁把这块知识点整理回顾一下。
先说说JNI和NDK的区别:
NDK (Native Development Kit) 是google提供个一套工具,包括:
从C / C++生成原生代码库所需要的工具和build files。总之,它可以自动生成.so文件,并且和java文件一起打包生成apk。
将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files ,即.apk文件)中。支持所有未来Android平台的一些列原生系统头文件和库
JNI (Java Native Interface) 是java的本地调用,通过这种机制使得在java中可以引用其他语言写的代码,通常是c/c++。JNI是java的特性,与android无关。
学习NDK之前需要先掌握JNI的使用规范,简单的说JNI有如下使用步骤:
1.编写java中的调用类
2.用javah生成c/c++原生函数的头文件
3.编写c/c++文件实现原生函数
4.(linux下)生成.so文件,windows下生成dll文件
5.将项目依赖的所有原生库和资源加入到java项目的java.library.path
6.生成java程序
详见:http://blog.youkuaiyun.com/funnyskyf/article/details/5694152 (有一些小错误)
下面准备在linux下编写一个简单的apk,功能是在屏幕上显示通过c代码获取的字符串。
一、NDK开发环境的搭建
到google官网下载android-ndk-r8d-linux-x86.tar.bz2,解压缩:
设置环境变量:
在最后添加:
export NDK_HOME=/home/administrator/develop/Android/android-ndk-r8d
export PATH=$NDK_HOME:$PATH
二、代码编写
1.新建一个android项目工程
2.编写主activity的代码:
public class TestNDK extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_test_ndk);
TextView myTextView = new TextView(this);
myTextView.setText( stringTestNdk() );
setContentView(myTextView);
}
public native String stringTestNdk ();
static {
System.loadLibrary("testNDK");
}
}
3.手动生成头文件
注:class文件在<项目>/bin/classes/中,可手动在项目根目录建立jni文件夹,或命令完成。
-d表示存放位置,ndk-bulid默认查找文件夹jni。
命令中“TestNDK”为java文件名,且首字母必须大写。com.example.testndk为包名。
4.编写c/c++文件
#include <string.h>
#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_example_testndk_TestNDK_stringTestNdk(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env,"Hello TestNDK");
}
注:放在jni目录下
5.编写android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=testNDK
LOCAL_SRC_FILES :=testNDK.c
include $(BUILD_SHARED_LIBRARY)
注:和.c文件放在同一目录
三、生成.so共享文件库
进入项目的jni目录或工程目录下,输入:
成功后显示:
四、在模拟器上运行程序:
这样用NDK编写android程序就算完成了,在jni目录中有:
可能遇到的错误:
1.……point to an unknown file : /…/jni/Android.mk
原因:这是因为ndk-build会查找工程下的jni目录,如果没有在这个路径找到Android.mk文件就会报错。
2.Fatal error : invalid -march option: ‘armv5te'
原因:一些编译器的链接文件丢失,一般在解压ndk压缩文件时出现。
解决:重解压,重下载,或手动建立链接文件。