## 第一次使用Android NDK,网上的教程都有些过时,写下来供需要的人参考

来源:互联网 发布:淘宝展现机制是什么 编辑:程序博客网 时间:2024/04/26 23:55

本人使用MAC 版本Eclipse Mars,自己配置的ADT(自带CDT工具),ADT的配置这里就不做说明了,可以google到一堆,接下来主要介绍NDK的安装和使用:

  • NDK的安装
  • 一个c++的JNI小例子(c和c++格式会有些不同,可去google了解)

NDK安装

  • 最新版本的NDK已经不需要再安装cygwin(用于模拟linux环境)、CDT插件了,安装起来更简单,首先到http://developer.android.com/tools/sdk/ndk/index.html(被墙了,需要翻墙才行)去下载最新的NDK版本android-ndk-r10e,注意你的系统是32位还是64位的,下载对应的版本即可。下载之后解压出来,大约3个G左右,把解压的文件夹复制到自己平时开发的工作目录(目录不要包含空格符号,在C/C++环境编译时有可能报错),比如我的放在/Users/KS/Documents/Android_sdk_ndk_mosx/android-ndk-r10e目录,这个文件夹路径就是后边的各种编译路径和头文件存放位置,具体作用和配置见下文。
  • 把NDK导入到Eclipse中,类似Android SDK,打开 “偏好设置”(windows系统是Windows>>Preferences)>>“Android”>>”NDK”,点击右边的Browse找到上一步的NDK存放目录,如下图所示。添加NDK路径
  • 接下来要把NDK路径添加到Eclipse的JNI默认编译环境。打开 “偏好设置”(windows系统是Windows>>Preferences)>>”C/C++”>>”Build”>>”Environment”。点击右边的”Add”按钮,添加NDK的环境,如下图:
    配置NDK环境
    Name就是环境变量的名字,随便取,我这里叫“NDKROOT”;Value就是上一步中的NDK文件目录/Users/KS/Documents/Android_sdk_ndk_mosx/android-ndk-r10e。添加了这个环境,就是告诉eclipse以后所有的JNI工程编译C/C++的时候都去这个路径找编译命令,这个路径会自动出现在新建的JNI工程里作为默认的编译路径。

    接下来就可以着手JNI的开发了,下面使用一个完整的小例子来说明会遇到的问题和怎么去解决。

一个c++的JNI小例子

  • 这个例子中,有三个editText,一个TextView和一个Button,点击Button会传两个数字到C++计算两个数的和然后返回到界面,同时C++还会返回hello world的字符串显示在textview上。界面效果如下:
    这里写图片描述
  • 首先新建一个Android空工程,创建好基本的view,然后选中工程右键>>”Android Tools”>>”Add Native Support…”
    添加JNI输入库的文件名,比如“TestNDK”(最后的so会自动生成为libTestNDK.so)
    libName这时候会在工程中自动新建好jni文件夹,并在文件夹下新建Android.mk和TestNDK.cpp(文件名就是之前输入的库名),这个TestNDK.cpp就是要编译成so库的c++文件。
  • 接下来就要编写java文件了,好使用工具自动生成c++的*.h头文件。在android工程中的src文件夹中新建一个类,假设为JNITest.java,内容为native函数,用来调用c++的,代码如下:
public class JNITest {    public native int add(int a,int b);    public native String getHello();}
  • 接下来就要生成c++的*.h头文件了,要使用命令行完成,切换到工程所在的目录的src文件夹中(一定要是src文件夹,深一层浅一层都不行,都会出现找不到类的错误提示)
KS@KSdeMacBook-Pro Android$ cd TestNDK/KS@KSdeMacBook-Pro TestNDK$ lsAndroidManifest.xml  ic_launcher-web.png  proguard-project.txtassets               jni                  project.propertiesbin                  libs                 resgen                  obj                  srcKS@KSdeMacBook-Pro TestNDK$ cd src/KS@KSdeMacBook-Pro src$ lscom

然后运行javac com/ks/testndk/JNITest.java (包含native方法的类的路径),生成class文件,用于下一步生成*.h。
接着运行 javah com.ks.testndk.JNITest (注意格式,要使用“.”代替“/”,同时不可以有“.class”后缀)

KS@KSdeMacBook-Pro src$ javac com/ks/testndk/JNITest.javaKS@KSdeMacBook-Pro src$ javah com.ks.testndk.JNITestKS@KSdeMacBook-Pro src$ lscom                      com_ks_testndk_JNITest.h
  • 如果没有错误的话,会在src文件夹下生成对应的*.h文件。同时会在工程根目录下生成libs文件夹,后边生成的so库文件就会出现在这个文件夹里。如果出现找不到类或文件的错误是因为路径没有写对。
  • 接下来把生成的*.h文件移动到jni文件夹下,你会发现代码有错误
    error
    出现类似于”Unresolved inclusion: **##“的错误,这是由于没有找到jni.h头文件引起的,因为除了eclipse配置NDK的环境之外,还要配置每个工程的头文件包含路径,右键工程>>”Properties”>>”C/C++ General”>>”Path and Symbols”>>”Add”,添加之前NDK路径下的platforms文件夹里的头文件(先选择对应的android版本,再选对应的头文件(cpu架构相关),一般都是选择arm CPU架构的头文件)。
    jni.h。此时就不会再有错误了。
    • 下面要实现C++具体的代码了。(注意,c和c++格式并不一样)
#include <jni.h>#include <com_ks_testndk_JNItest.h>JNIEXPORT jint JNICALL Java_com_ks_testndk_JNITest_add(JNIEnv * jniEnv, jobject jObject, jint num1, jint num2){    jint result=num1+num2;    return result;}JNIEXPORT jstring JNICALL Java_com_ks_testndk_JNITest_getHello(JNIEnv * jniEnv, jobject jObject){    return jniEnv->NewStringUTF("hello world");}
  • 写好之后先编译c++文件(由于安装了CDT插件,会自动使用C++编辑器打开c++文件切换到c++工程,根据生成的android.mk 直接可编译c++文件,android.mk 类似于makefile文件,具体语法可以去google),没有错误会在libs文件夹下生成libTestNDK.so文件,这就是我们需要的so文件了。
    libso
  • 接下来就要在java中引用这个so文件了。
static{/**lib的前缀后缀都不能加,libTestNDK.so,只要写TestNDK就ok*/System.loadLibrary("TestNDK");  }

到此,JNI就可以正常运行了。完整代码

0 0
原创粉丝点击