NDK 10分钟入门教程
2015-06-29 16:55
369 查看
本文首先发表在http://www.hikyson.cn/archives/771
你可以在http://download.csdn.net/detail/hikyson/8850293找到文章的实例demo。
r10版本的ndk会有些变化导致原来的一些库不能用
配置环境变量
在
path的每个环境变量配置都需要用
配置完成之后启动cmd,输入ndk-build。如果看到下面这样就说明成功了。
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-build-cmd.png)
导入sample中的hellojni
导入成功之后可以先看一下项目结构,这时候除了普通的项目文件外还有一个jni的文件夹,里面是mk文件和.c文件,如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/hellojniproject.png)
打开cmd,cd到项目目录下
执行ndk-build命令
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-build-result.jpg)
这个命令是用来编译我们的ndk项目的,编译之后就会生成可以用的so库文件
这时候我们刷新一下项目,会发现多了两个文件夹。一个是lib,一个是obj。如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-hello-jni-pro-2.png)
运行hello-jni,如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/run-result.png)
注:如果是用genemotion运行的话需要安装arm-translation包,这个就自己网上找一个吧,很多。
注:如果刚才步骤出错了,可以运行
到这里,我们没有自己写过代码,也不知道hello-jni做了什么,仅仅就是一步步编译了一下别人的项目。不急,接下来我们就要自己写一个简单的ndk项目了。
这时候可以回头看看sample下的
在项目目录下,执行:
如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/javah-jni-h.png)
这个命令的确很麻烦,一个个参数解释下
最后一个指定需要编译的类路径,我们这里是编译的
这里还需要指定android.jar,因为我们的mainactivity是在android开发包下的
运行完javah命令cmd不会打印任何信息就说明可以了。
这时候刷新项目,我们会惊喜地看到,jni文件夹下有了一个.h文件。文件是由包名+类名以下划线分隔组成的。
include需要的头文件
实现函数
整个c文件的代码
android.mk是主要的配置,还有一个application.mk用来指定需要编译的平台。
android.mk拿过来之后需要修改一点东西,如下:
我们也可以看出来,刚才的
编译得到so文件。
静态加载
然后就可以调用我们写的native方法了,整个代码是这样的:
运行结果如下:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/hello-native-result.png)
写完收工~
你可以在http://download.csdn.net/detail/hikyson/8850293找到文章的实例demo。
准备工作
下载ndk r9d版本
地址:http://pan.baidu.com/s/1o6MKL2y 密码: usb2r10版本的ndk会有些变化导致原来的一些库不能用
配置ndk环境变量
把下载的ndk解压到任意目录下,比如我解压到了D:\application\AndroidDevelopTools\android-ndk-r9d目录下
配置环境变量
在
计算机 -> 属性 -> 高级系统设置 -> 环境变量下找到
path。在后面追加
D:\application\AndroidDevelopTools\android-ndk-r9d;
path的每个环境变量配置都需要用
;分隔开的
配置完成之后启动cmd,输入ndk-build。如果看到下面这样就说明成功了。
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-build-cmd.png)
hello jni
接下来我们先拿ndk自带的sample练练手。导入sample中的hellojni
hellojni项目在
android-ndk-r9d\samples\hello-jni目录下,导入到eclipse。
导入成功之后可以先看一下项目结构,这时候除了普通的项目文件外还有一个jni的文件夹,里面是mk文件和.c文件,如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/hellojniproject.png)
打开cmd,cd到项目目录下
执行ndk-build命令
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-build-result.jpg)
这个命令是用来编译我们的ndk项目的,编译之后就会生成可以用的so库文件
这时候我们刷新一下项目,会发现多了两个文件夹。一个是lib,一个是obj。如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ndk-hello-jni-pro-2.png)
运行hello-jni,如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/run-result.png)
注:如果是用genemotion运行的话需要安装arm-translation包,这个就自己网上找一个吧,很多。
注:如果刚才步骤出错了,可以运行
ndk-build clean,删除不用的二进制文件(就是so之类的),重新编译。
到这里,我们没有自己写过代码,也不知道hello-jni做了什么,仅仅就是一步步编译了一下别人的项目。不急,接下来我们就要自己写一个简单的ndk项目了。
创建自己的NDK项目
1. 创建项目
创建一个普通的项目HelloNative,在
mainactivity里添加一个
native方法:
public static native String getStringFromNative();
这时候可以回头看看sample下的
hello-jni了,你可以在它的代码中看到native方法
public native String stringFromJNI();和
public native String unimplementedStringFromJNI();
2. 创建jni目录
在项目根目录下创建一个文件夹,叫jni。
3. 生成.h头文件
我们就需要用一个工具javah用来生成头文件。
在项目目录下,执行:
javah -classpath bin/classes;D:application\AndroidDevelopTools\sdktools\platform\android-22\android.jar -d jni com.example.hellonative.MainActivity
如图:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/javah-jni-h.png)
这个命令的确很麻烦,一个个参数解释下
-classpath就是指定用于生成头文件的class文件,大家都知道java代码会首先编译成class文件,这边就是用的这个。android项目编译之后的class文件都放在bin下的。
-d就是输出目录到jni。
最后一个指定需要编译的类路径,我们这里是编译的
MainActivity类。
这里还需要指定android.jar,因为我们的mainactivity是在android开发包下的
运行完javah命令cmd不会打印任何信息就说明可以了。
这时候刷新项目,我们会惊喜地看到,jni文件夹下有了一个.h文件。文件是由包名+类名以下划线分隔组成的。
javah应该在你安装java的时候就已经配置好了环境变量了的,如果cmd运行javah告诉你识别不了命令,就网上找个教程配置一下吧,这边不赘述了。
4. 编写C代码
我们从刚才生成的头文件中拷贝需要实现的函数头JNIEXPORT jstring JNICALL Java_com_example_hellonative_MainActivity_getStringFromNative (JNIEnv * env, jclass jcls)
include需要的头文件
[code]#include <string.h> #include <jni.h> #include "com_example_hellonative_MainActivity.h"
实现函数
Java_com_example_hellonative_MainActivity_getStringFromNative
整个c文件的代码
[code]#include <string.h> #include <jni.h> #include "com_example_hellonative_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_hellonative_MainActivity_getStringFromNative
(JNIEnv * env, jclass jcls){
return (*env)->NewStringUTF(env, "www.hikyson.cn from native");
}
5. 编写mk文件
mk文件是用来编译c代码的脚本文件,一般来说我们直接把sample中的android.mk拿过来就可以了android.mk是主要的配置,还有一个application.mk用来指定需要编译的平台。
android.mk拿过来之后需要修改一点东西,如下:
[code]LOCAL_MODULE := hello-native LOCAL_SRC_FILES := hello-native.c
LOCAL_MODULE指定了生成的so文件名,最后生成的so文件是
lib+LOCAL_MODULE+.so
LOCAL_SRC_FILES指定了需要编译的文件
6. 生成so库
前面已经有了头文件,根据头文件写好了对应的c代码,而且也有了mk编译脚本,所有事情都已经完备,只欠编译,就像上文编译sample一样,我们执行ndk-build命令。
我们也可以看出来,刚才的
hello-jnisample是已经把当前步骤之前的所有东西都做了的。
编译得到so文件。
7. 使用so库
这个就比较简单了,看代码:[code] static{ System.loadLibrary("hello-native"); }
静态加载
hello-native,这个名字是
LOCAL_MODULE指定的,不要写错。
然后就可以调用我们写的native方法了,整个代码是这样的:
[code]public class MainActivity extends Activity { static { System.loadLibrary("hello-native"); } public static native String getStringFromNative(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((TextView) this.findViewById(R.id.text)) .setText(getStringFromNative()); } }
运行结果如下:
![](https://git.oschina.net/cocobaby/kyson_public_log/raw/master/hikyson.cn/NDK10%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/hello-native-result.png)
写完收工~
相关文章推荐
- MySQL表空间的碎片整理
- poj 2777
- hdu 3394 railway 点连通分量判环
- C#高级编程三十二天----数组基础
- GDAL 生成shp文件
- Android Studio生成apk
- MAC系统IntelliJ Idea 14 常用快捷键汇总
- 剥下“java.lang.OutOfMemoryError: unable to create new native thread”的外衣
- mAdapter.notifyDataSetChanged()无法更新UI
- 13. Roman to Integer
- SQL SERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则
- Jpush推送出现Please refer to JPush docs
- Low Power之CPF/UPF
- 高斯判别分析
- 好久没更新了
- OAuth 2.0系列教程(四) 客户端类型
- iOS 客户端学习-支付宝
- jquery 选择器
- linux中查找,which和whereis
- sql语句按照汉字拼音首字母排序