Android NDK 开发教程(极客学院)

一、Android NDK环境搭建

使用最新ndk,直接抛弃cygwin,以前做Android的项目要用到NDK就必须要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量,特别麻烦,新版就不需要了。

方法/步骤

  1. Android官网下载Android的开发工具ADT(Android Development Tool的缩写),该工具集成了最新的ADT和NDK插件以及Eclipse,还有一个最新版本SDK,解压之后就可以用了。
  2. ADT插件:管理Android SDK和相关的开发工具的

    NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件 。下载链接见:http://developer.android.com/sdk/index.html

  3. Android官网下载最新的NDK,注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。

    下载链接见:http://developer.android.com/tools/sdk/ndk/index.html

eclipse配置

解压ndk并配置环境变量:添加系统环境变量NDK_ROOT为: D:\Android\android-ndk-r10d。

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

    (如果没有ndk选项,则可能是因为没有ndk插件,自行下载一个放入\eclipse\plugins\下重启即可)

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

     
    这时候工程就会多一个jni的文件夹,jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的源文件。
     
  3. 接下来仿着NDK的demo,Hello-JNI工程写一下。使用Alt + '/'可以代码提示!很爽!有木有?

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

     
     
     
  5. 完成了,然后运行。运行之前先编译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)

  1. extern "C" {
    JNIEXPORT jstring JNICALL ava_com_wytiger_jnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz);
    }

  2. JNIEXPORT jstring JNICALL ava_com_wytiger_jnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )
  3. {
  4. return env->NewStringUTF("Hello from JNI bear c++");
  5. }

原因是:

被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开发的更多相关文章

  1. Android NDK开发Hello Word!

    在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下NDK开发的魅力.这里我们选择使用C+JAVA开发Android ...

  2. Android NDK开发初识

    神秘的Android NDK开发往往众多程序员感到兴奋,但又不知它为何物,由于近期开发应用时,为了是开发的.apk文件不被他人解读(反编译),查阅了很多资料,其中有提到使用NDK开发,怀着好奇的心理, ...

  3. Android NDK 开发(四)java传递数据到C【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处 ...

  4. Android NDK 开发(三)--常见错误锦集合Log的使用【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511  Android NDK开发经常因某些因素会出现一些意想不到的错误, ...

  5. Android NDK 开发(二) -- 从Hlello World学起【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41805719  上篇文章讲述了Android NDK开发的一些基本概念,以及NDK ...

  6. android NDK开发环境搭建

    android NDK开发环境搭建 2012-05-14 00:13:58 分类: 嵌入式 基于 Android NDK 的学习之旅-----环境搭建 工欲善其事必先利其器 , 下面介绍下 Eclip ...

  7. !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结

    http://hujiaweibujidao.github.io/blog/2013/11/18/android-ndk-and-opencv-development-3/ Android Ndk a ...

  8. Android NDK开发及调用标准linux动态库.so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  9. Android NDK开发method GetStringUTFChars’could not be resolved

    Android NDK开发method GetStringUTFChars'could not be resolved 图1 最近用到android的ndk,但在eclipse中提示method Ge ...

随机推荐

  1. Sublime3安装过程及常用插件安装及常用快捷键

    1  先去http://www.sublimetext.com/官网下载软件,然后网上找一个验证码,注册完成. 2  安装Package Control ,Package Control 插件是一个方 ...

  2. 十步完全理解SQL

    转载于:http://blog.jobbole.com/55086/ 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序 ...

  3. wk_01

    Python 学习环境搭建 pyenv是个多版本python管理器,可以同时管理多个python版本共存,如pypy,miniconde等等.我们安装时其会将pyenv安装在当前用户家目录中的.pye ...

  4. 见鬼了,swiper

    1.今天不知怎么swiper的onInit函数不起作用,怎么弄都不行: 把以前能行的案例的包都导进去还是不行,但是onSlideChangeEnd可以触发,晕死了.... 不,它触发了一次onInit ...

  5. js,onblur后下一个控件获取焦点判断、html当前活跃控件、jquery版本查看、jquery查看浏览器版本、setTimeout&setInterval

    需求: input控件在失去焦点后直接做验证,验证通不过的话,显示相应错误.但是如果失去焦点后点击的下个控件是比较特殊的控件(比如,退出系统),那么不执行验证操作,直接退出系统(防止在系统退出前,还显 ...

  6. handlebars+require

    handlebars+require 最近在某网站看到了handlebars.js,出于好奇就百度了下这是神马玩意,结果让我很是欢喜,于是就开始自学下,handlebars就几个方法,蛮简单,言归正传 ...

  7. iptables案例手册

    Linux防火墙Iptable如何设置只允许某个ip访问80端口,只允许特定ip访问某端口 iptables常用实例备查(更新中) 9个常用iptables配置实例 案例: http://www.cn ...

  8. QT 文件操作

    QT提供了QFile类用于文件读写 QFile可以读写文本文件,也可以读写二进制文件 #include "widget.h" #include <QGridLayout> ...

  9. TinyFrame开篇:基于CodeFirst的ORM

    前言 做项目的这段时间,由于比较忙,一直没有机会闲下来思考.正好趁目前手头活儿轻松点,就花了一两天时间搭建了一个比较简单的框架,名称暂时就叫做:TinyFrame吧.顾名思义,就是微框架的意思.虽然这 ...

  10. Java面试知识点总结

    本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有一定的Java基础:若您初涉 ...