/***************************************************

*TODO: description .

* @author: gao_chun

* @since: 2015-3-30

* @version: 1.0.0

* @remark: 转载请注明出处

**************************************************/


下载Android开发工具,这里使用Eclipse,若无法下载,可查看

Android官网无法下载eclipse-adt-bundle:http://blog.csdn.net/gao_chun/article/details/41010629


下载后若Android SDK无法正常更新,可查看

Android SDK无法更新终极解决方式http://blog.csdn.net/gao_chun/article/details/37971461


在android ndk r7之后,已经不用下载安装Cygwin(模拟Linux环境),在以往的NDK开发中必须要下载,且需下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量,等等。太过于麻烦。

一、介绍下NDK是什么东西

1.NDK是一系列工具的集合
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
2.NDK提供了一份稳定、功能有限的API头文件声明
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。


二、为什么使用NDK

  1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

  2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。

  3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。

  4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。


三、下载NDK之后,解压便可


注:1.在android-ndk-r10c目录下有一个samples的目录,里面存放着例子,可供学习。


2.注意NDK的环境变量,如:



四、在Eclipse的Window->Preferences->Android->NDK,设置NDK路径,例如:


注:需检查ADT插件是否安装了Android Native Delelopment Tools(可在Eclipse - Help - Install new Software中检查)


五、新建一个Android工程后,在new出来的Project上右键点击Android Tools->Add Native Support...给库文件(.so)取个名字,如:hello


这时你会发现工程会多一个jni的文件夹,jni下有Android.mk和hello.cpp文件。

Android.mk是NDK工程的Makefile,hello.cpp就是NDK的源文件。

有关Android.mk文件的介绍:http://blog.csdn.net/gao_chun/article/details/44656169


六、我们在hello.cpp中写下如下代码,可以参考samples目录中的hello-jni例子。

#include <jni.h>extern "C" {JNIEXPORT jstring JNICALL Java_com_hello_Main_stringFromJNI(JNIEnv *env,    jobject thiz) {  return env->NewStringUTF("Hello jni");}}

C代码中是:

return (*env)->NewStringUTF(env,"Hello jni!");

C++代码是:

return env->NewStringUTF("Hello jni!");


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

这里需要注意一点,按照如下的方式写,在程序运行后是报错的(注:是程序运行后会报错,不是该文件有错,该文件有错是因为java编辑器没有安装支持C/C++的插件所导致,在该文件编写完成后可以colse项目从新打开便可,或者clean):



报错信息如下:



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


七、Main.java :

package com.hello;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class Main extends Activity {    //静态方法优先加载    static {        System.loadLibrary("hello");    }    //声明jni层的原生方法,使用native关键字    public native String stringFromJNI();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView  tv = new TextView(this);        tv.setText(stringFromJNI());        setContentView(tv);    }}

注:static代码块里面用System.loadLaibrary加载的是编译器编译完成后的.so库,并非hello.cpp文件。


八、完成,运行就ok。



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

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



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


3.再编译就ok!


如果觉得文章对你有用,点个赞将是我最大的动力!

更多相关文章

  1. Android(安卓)Camera代码位置
  2. android之luncher滑动效果
  3. Dealing with bitmap object in android NDK
  4. 重载android返回键响应函数
  5. Android(安卓)去掉title bar的3个方法
  6. android常用的代码片段
  7. Timer使用
  8. Android主流IOC框架浅析(Java注解反射原理)
  9. 箭头函数的基础使用

随机推荐

  1. 解析SQL Server聚焦移除(Bookmark Lookup
  2. 详解SQL Server的聚焦过滤索引
  3. 浅述SQL Server的聚焦强制索引查询条件和
  4. 浅析SQL Server的分页方式 ISNULL与COALE
  5. 详解SQL Server中的数据类型
  6. 浅析SQL Server的聚焦使用索引和查询执行
  7. 浅析SQL Server 聚焦索引对非聚集索引的
  8. VS2015安装之后加装Sql server2014详细步
  9. 详解SQL Server的简单查询语句
  10. 详解SQL Server数据库架构和对象、定义数