Android NDK 开发教程(极客学院)
一、Android NDK环境搭建
使用最新ndk,直接抛弃cygwin,以前做Android的项目要用到NDK就必须要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量,特别麻烦,新版就不需要了。
方法/步骤
- Android官网下载Android的开发工具ADT(Android Development Tool的缩写),该工具集成了最新的ADT和NDK插件以及Eclipse,还有一个最新版本SDK,解压之后就可以用了。
- ADT插件:管理Android SDK和相关的开发工具的
;
NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件 。下载链接见:http://developer.android.com/sdk/index.html
- Android官网下载最新的NDK,注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。
下载链接见:http://developer.android.com/tools/sdk/ndk/index.html
eclipse配置
解压ndk并配置环境变量:添加系统环境变量NDK_ROOT为: D:\Android\android-ndk-r10d。
-
打开Eclipse,点Window->Preferences->Android->NDK,设置NDK路径,例如Shamoo的是E:\android-ndk-r9c
(如果没有ndk选项,则可能是因为没有ndk插件,自行下载一个放入\eclipse\plugins\下重启即可)
-
新建一个Android工程,在工程上右键点击Android Tools->Add Native Support...,然后给我们的.so文件取个名字,例如:my-ndk
这时候工程就会多一个jni的文件夹,jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的源文件。 接下来仿着NDK的demo,Hello-JNI工程写一下。使用Alt + '/'可以代码提示!很爽!有木有?
-
JNI接口的命名规范是:Java_ + 调用该方法的包名(包名的点用_代替) + _ + 调用该接口的类名 + _ + 方法名,对于实例方法,有两个参数是必要的,一个JNI的环境指针JNIEnv *
完成了,然后运行。运行之前先编译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.再编译,问题就解决啦!
问题二、使用c++来编写本地库,会有一些兼容问题。
(1)直接黏贴HelloJni的stringFromJNI函数过来测试,提示Method 'NewStringUTF' could not be resolved
解决方法:将(*env)->NewStringUTF(env, "Hello from JNI !")改为return env->NewStringUTF("Hello from JNI !")即可
原因是:NDK plugin默认为我们生成的是cpp文件,而C与C++调用函数的参数不一致,因此找不到函数,具体参考jni.h中的定义。cpp文件中形如(*env)->Method(env, XXX)改成env->Method(XXX)即可。
(2)运行c++生成的.so库,若报以下错误:(既找不到函数)
No implementation found for native Lcom/dgut/android/MainActivity;.stringFromJNI ()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: stringFromJNI
at com.dgut.android.MainActivity.stringFromJNI(Native Method)
解决方法:
为供Java调用的c++函数前加入extern "C" 修饰,如:(NDK example里面的cpp文件也是这么声明的,参考hello-gl2)
extern "C" {
JNIEXPORT jstring JNICALL ava_com_wytiger_jnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz);
};- JNIEXPORT jstring JNICALL ava_com_wytiger_jnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )
- {
- return env->NewStringUTF("Hello from JNI bear c++");
- }
原因是:
被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。
首先看看C++中对类似C的函数是怎样编译的:作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数voidfoo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。
同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。
因此,若我们没有使用extern "C"修饰函数,按照C语言方式编译和连接,Jni调用将可能找不到该函数。
问题三、Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml (这个是NDK工具的一个BUG,若build Target大于minSdkVersion,则会报这个错误,导致无法运行)
解决方法:在Application.mk文件中添加APP_PLATFORM := android-8
问题四、Type 'jint' could not be resolved, and JNIEnv, jclass
Project Properties -> C/C++ General -> Path and Symbols,选择include标签,Add -> $Android_NDK_HOME/platforms/android-14/arch-arm/usr/include
选中All languages. 最后Apply -> OK
Android NDK开发的更多相关文章
-
Android NDK开发Hello Word!
在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下NDK开发的魅力.这里我们选择使用C+JAVA开发Android ...
-
Android NDK开发初识
神秘的Android NDK开发往往众多程序员感到兴奋,但又不知它为何物,由于近期开发应用时,为了是开发的.apk文件不被他人解读(反编译),查阅了很多资料,其中有提到使用NDK开发,怀着好奇的心理, ...
-
Android NDK 开发(四)java传递数据到C【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处 ...
-
Android NDK 开发(三)--常见错误锦集合Log的使用【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511 Android NDK开发经常因某些因素会出现一些意想不到的错误, ...
-
Android NDK 开发(二) -- 从Hlello World学起【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41805719 上篇文章讲述了Android NDK开发的一些基本概念,以及NDK ...
-
android NDK开发环境搭建
android NDK开发环境搭建 2012-05-14 00:13:58 分类: 嵌入式 基于 Android NDK 的学习之旅-----环境搭建 工欲善其事必先利其器 , 下面介绍下 Eclip ...
-
!! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
http://hujiaweibujidao.github.io/blog/2013/11/18/android-ndk-and-opencv-development-3/ Android Ndk a ...
-
Android NDK开发及调用标准linux动态库.so文件
源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...
-
Android NDK开发method GetStringUTFChars’could not be resolved
Android NDK开发method GetStringUTFChars'could not be resolved 图1 最近用到android的ndk,但在eclipse中提示method Ge ...
随机推荐
-
fir.im Weekly - 让 iOS 应用更加安全
攻易防难,关于 iOS 应用安全看起来有些神秘.iOS Security , 源于@吴发伟_则平博客翻译的关于iOS安全的一系列文章,现在站点已经系统收集了大量关于 iOS 逆向.安全.反编译.静动态 ...
-
neon指令,注意事项
1. vbic_s8 (int8x8_t a, int8x8_t b) 是 ~(ai & bi),一开始理解成 (~ai )& bi 导致出错 2.uint8x8_t vqshrn ...
-
使用git管理github上的项目
使用git可以把我们的项目代码上传到github上面去,方便自己管理,如何使用git?觉得是每位程序猿所必需要有的谋生技能,所以在此记录一下自己学会使用的这个过程: 一.需要注册github账号,这样 ...
-
RMAN数据库异机迁移
本文讲述如何用rman将一个库迁移到另一个服务器上. 服务器A:linux es4 + oracle9204 (源)服务器B:linux es4 + oracle9204 (目标) 一.创建目录 为了 ...
-
web前端学习路线和步骤
H5+全栈工程师 (学习下列技术可以加QQ: 1416 7596 61)第一阶段:初级入门阶段基本功 1.HTML入门 Windows概述.浏览器概述.HTML简介.HTML标签详解.前端开发工具概 ...
-
c#一些特殊语法
1.using 语法 using不仅可以作为导入包,重命名类名.还可以释放资源 using (Pen gridLinePen = new Pen(Color.red)) { e.Graphics.Dr ...
-
将gbk字符串转换成utf-8,存储到注册表中后,再次从注册表读取转换成gbk,有问题!!!
char *a = "新2新"; printf("gbk:'%s'\n", a); int ii; ; ii < strlen(a); ii++) { p ...
-
Git更新本地仓库
1.查看远程仓库git remote -v2.从远程获取最新版本到本地git fetch origin master:temp3.比较本地的仓库与远程仓库的区别git diff temp4.合并tem ...
-
Linux命令学习之路——档案拷贝:cp
使用权限:所有角色 使用方式:cp [ -arf ] source dest / cp [ -arf ] source... Directory 作用:把一个档案拷贝到另一个档案(档案复制),或将多个 ...
-
FatMouse&#39;s Speed (hdu 1160)
#include <iostream> #include <cstdio> #include <cstring> #include <algori ...