以前做Android的项目要用到NDK就必须要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量...


麻烦到不想说了,Shamoo在网上查了一下资料,发现了一个超级快配置NDK的办法。

Step1:到Android官网下载Android的开发工具ADT(Android Development Tool的缩写),该工具集成了最新的ADT和NDK插件以及Eclipse,还有一个最新版本SDK。解压之后就可以用了,非常爽!

ADT插件:管理Android SDK和相关的开发工具的

NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件

也可以在线更新ADT、NDK插件,不过速度超级慢...所以果断在网上下载集成开发工具ADT,下载链接见:http://developer.android.com/sdk/index.html


Step2:到Android官网下载最新的NDK,注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。比起下载Cygwin要方便多啦!下载链接见:http://developer.android.com/tools/sdk/ndk/index.html

下载完成之后,解压搞定!


Step3:打开Eclipse,点Window->Preferences->Android->NDK,设置NDK路径,例如Shamoo的是E:\android-ndk-r9c

Step4:新建一个Android工程,在工程上右键点击Android Tools->Add Native Support...,然后给我们的.so文件取个名字,例如:my-ndk

这时候工程就会多一个jni的文件夹,jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的源文件。


Step5:接下来仿着NDK的demo,Hello-JNI工程写一下。使用Alt + '/'可以代码提示!很爽!有木有?之前用CDT时候死活都按不出代码提示,郁闷...


JNI接口的命名规范是:Java_ + 调用该方法的包名(包名的点用_代替) + _ + 调用该接口的类名 + _ + 方法名,对于实例方法,有两个参数是必要的,一个JNI的环境指针JNIEnv *,另一个是调用该方法的Java实例jobject

my-ndk.cpp:

[cpp] view plain copy print ?
  1. #include<jni.h>
  2. JNIEXPORTjstringJNICALLJava_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv*env,
  3. jobjectthiz){
  4. returnenv->NewStringUTF("Hellojni");
  5. }

TestActivity.java:

[java] view plain copy print ?
  1. publicclassTestActivityextendsActivity{
  2. static{
  3. System.loadLibrary("my-ndk");
  4. }
  5. //声明JNI层的原生方法,使用native关键字
  6. publicnativeStringstringFromJNI();
  7. @Override
  8. protectedvoidonCreate(BundlesavedInstanceState){
  9. super.onCreate(savedInstanceState);
  10. TextViewtvText=newTextView(this);
  11. tvText.setText(stringFromJNI());
  12. setContentView(tvText);
  13. }
  14. }

使用ndk库必须在static代码块里面用System.loadLaibrary加载.so库


Step6:完成了,然后运行。运行之前先编译NDK,然后在编译JAVA代码。编译也许会遇到Unable to launch cygpath. Is Cygwin on the path?错误,解决办法如下:

1.工程右键,点Properties->C/C++ Build的Building Settings中去掉Use default build command,然后输入${NDKROOT}/ndk-build.cmd

2.在C/C++ Build中点击Environment,点Add...添加环境变量NDKROOT,值为NDK的根目录

3.再编译,问题就解决啦!


运行时崩溃,遇到java.lang.UnsatisfiedLinkError: stringFromJNI错误,解决办法:在C++文件中函数定义前添加extern "C"修饰

[cpp] view plain copy print ?
  1. extern"C"{
  2. JNIEXPORTjstringJNICALLJava_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv*env,
  3. jobjectthiz);
  4. }
  5. JNIEXPORTjstringJNICALLJava_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv*env,
  6. jobjectthiz){
  7. returnenv->NewStringUTF("Hellojni");
  8. }


原因是:使用extern "C"修饰,编译器会按C语言的方式编译和连接。在C语言中,函数编译之后函数名与C++函数编译之后不同,例如foo(int x, int y),C可能会编译成_foo的名字,而C++因为支持重载,所以会编译成像_foo_int_int这种带参数的函数名。如果是按照C语言的编译方式,调用foo函数是找不到_foo的函数名就会报出函数名找不到的错误。所以要添加extern "C"修饰。

原文:http://blog.csdn.net/pocoyoshamoo/article/details/23533923

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)自定义View - 启航 一般View定义
  3. MOTODEV Studio for Android(安卓)安装 注意
  4. android.widget.Toast——快显信息
  5. Android(安卓)ImageSpan与TextView中的text居中对齐问题解决(无论
  6. Android的安装和配置【Z】
  7. Android使用Aidl实现跨进程通信
  8. Android(安卓)studio 解决Android(安卓)Library Project jar包重
  9. lambda表达式介绍以及Android(安卓)Studio引入lambda

随机推荐

  1. android使用百度地图SDK 去掉百度Logo的
  2. 学习Android(一)
  3. Android(安卓)之 Shape (圆角输入框)
  4. android的两种布局---------------------
  5. Android中使用继承GDActivity出现的问题
  6. Android(安卓)将每三个数字加上逗号处理(
  7. PHP 判断当前扫码的客户端浏览器类型
  8. Android Foreground Service
  9. Android之Fragment动态加载、Fragment与A
  10. Android NDK + adb调试