Android下jni开发之ndk的使用
一、简介
JNI和NDK很多Android开发初学者没有搞明白这个问题,JNI是Java调用Native机制,是Java语言自己的特性全称为Java Native Interface,类似的还有微软.Net Framework上的p/invoke,可以让C#或Visual Basic.Net可以调用C/C++的API,所以说JNI和Android没有关系,在PC上开发Java的应用,如果运行在Windows平台使用JNI是是经常的,比如说读写Windows的注册表。而NDK是Google公司推出的帮助Android开发者通过C/C++本地语言编写应用的开发包,包含了C/C++的头文件、库文件、说明文档和示例代码,我们可以理解为Windows Platform SDK一样,是纯C/C++编写的,但是Android并不支持纯C/C++编写的应用,同时NDK提供的库和函数功能很有限,仅仅处理些算法效率敏感的问题
简单点说,用C语言生成一个库文件,在java中调用这个库文件的函数。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
1、编写包含native本地方法的java类
2、通过javah工具生成C/C++语言的头文件
3、使用C/C++语言实现头文件
4、使用交叉编译工具对C/C++本地代码进行编译,最后通过链接生成*.so可执行的C/C++库
5、实际执行Java代码去和本地的C/C++代码互相沟通
二 、NDK开发环境的搭建
1.下载安装Android NDK
2.NDK环境配置 http://jingyan.baidu.com/article/ff42efa91906b8c19e220234.html
三、通过链接生成*.so可执行的C/C++库
打开cmd,进入jni目录,执行ndk-build命令,如果ndk-build执行不了,回到上一条环境配置
四、执行ndk-build命令 遇到的问题
1.android.mk: *** missing separator (did you mean TAB instead of 8 spaces?)或者*** missing separator的解决办法
http://blog.csdn.net/z13144099248m/article/details/41800747
这个错误是由于在编写这个文件的时候,行前面用的是空格,而不是tab,所以造成了操作符丢失的错误。
解决办法是:把缩进的空格delete掉,然后按tab键用tab代替4个空格。
2、android.mk: ***commands commence before first target.的原因
http://blog.csdn.net/dahaibeibe/article/details/8162955
上一行换行符号 \ 后面有空格
本行前面的空白有非法字符
3.android.mk: *** missing separator missing separator的解决办法
http://blog.csdn.net/sunnyfans/article/details/8807427
总而言之,这三问题都是操作符有问题,建议删除行前行后的空格用Tab/回车代替,所有的空格都有可能有问题,所以如果是粘贴过来的android.mk需要注意下格式等要求,其他的问题以后遇到i补充i
4.运行成功后,在android 6.0 会报java.lang.UnsatisfiedLinkError: No implementation found for intcom.gauss.speex.encode.Speex.open(int) (tried Java_com_gauss_speex_encode_Speex_open and Java_com_gauss_speex_encode_Speex_open__I)这个错误
http://blog.csdn.net/donglynn/article/details/25377067
问题显然是没有找到相应的本地函数。解决办法也很简单,就是Java代码,.h文件和.cpp文件中的声明,肯定有一个不对应的。
我是由于包名com.gauss.speex.encode.和粘贴过来的代码不一致,自己生成.h文件和copy过来的.cpp文件中方法名不一致导致的找不到相应的 本地函数,坑爹的是这么明显的错编译竟然不报错
五、android实现jni的步骤
(对这个我开始一直很混乱,百度了资料看了还是混乱,第二次android下jni下使用speex终于清晰点了,以下是当时参考链接,混乱时再跟着走一 遍就ok)
speex算法在android上的移植 http://blog.csdn.net/zkw12358/article/details/25339003
speex编解码在android上实现 http://blog.csdn.net/xyz_lmn/article/details/8013490
android SDK使用cygwin编译.so文件 http://blog.csdn.net/zkw12358/article/details/24560499
Android移植live555之二:android平台下jni的使用 http://blog.163.com/oceanwave@yeah/blog/static/69429295201398115116782/