Android下jni开发之ndk的使用(下载、配置、编译遇到的问题)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zri323/article/details/52489502

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就是简化了这个过程。


    Java通过JNI机制和C/C++沟通的具体步骤

    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/


 







猜你喜欢

转载自blog.csdn.net/zri323/article/details/52489502