最近由于项目的需要,使用到了Android的NDK技术,对项目核心算法跨平台的移植。简答而言,就是使用C对原来的算法进行了改进,并集成到原 来的app项目里。

从前的项目一直没有使用NDK进行开发的机会,因而一直仰慕那些技术大牛们关于NDK以及C/C++开发而写的文章,觉得很深奥,因而一直蠢蠢欲动。

其实NDK的开发并不复杂,就入门而言甚至可以说是easy job,觉得它难是难于C/C++代码的编写与调试。这个是我最近从事NDK开发的一点感受!

首先,我们要弄懂几个概念,何为NDK,它和SDK以及JNI有什么关系?请前看下图:

JNI (Java Native Interface),Java的本地接口

JNI是Java众多开发技术中的一门,意在利用本地代码,为Java程序提供 更高效,更灵活的拓展。应用场景包括:对运行效率敏感的算法实现、跨平台应用移植、调用系统的底层驱动、调用硬件等。尽管Java一贯以其良好的跨平台性 而著称,但真正的跨平台之王,应该是C/C++,因为当前世上90%的系统都是基于C/C++编写的。Java的跨平台,是以牺牲效率换来对多种平台的兼 容性,因而JNI可以说是Java短板的补充!举一例子说明,当前流行的移动操作系统Android,一直被说系统操作的流畅性不如IOS,原因在于 Android的App是基于Java开发的,IOS的是基于Object-C开发的,区别在于同样的操作,在IOS上一条指令完成,在Android上 则需要多大三条指令才能完成(数据来自于网络,不一定准确)!于是在Android JellyBean版本中,Google为其引入ProjectButter(黄油计划),在应用层大量使用了本地库,并优化了系统的架构,以提升 Android系统整体的操作反应!

咔咔,JNI的介绍就先说到这里,总之,JNI是一门技术,是Java Code和C/C++ Code联系的桥梁!

JNI开发的流程

1、编写Java Code,如下面的例子:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

Toast.makeText(getApplicationContext(), sayHellow(), Toast.LENGTH_LONG).show();
}

public native String sayHellow();  //调用本地方法

static {
              System.loadLibrary("Scgps_Client");  //加载本地共享库
        }

}

2、编写C/C++ Code,如下面的例子:

#include
#include

JNIEXPORT jstring JNICALL Java_com_scgps_client_MainActivity_sayHellow(JNIEnv* env, jobject thiz)
{
const char * ret = "Hellow Form Ndk";
        return (*env)->NewStringUTF(env, ret);
}

3、编译 C/C++ Code,成功并得到本地共享库

本地共享库是Linux下的叫法,文件扩展名是.so,windows下叫动态链接库,文件扩展名是.dll。前 面说到C/C++才是跨平台之王,这就是其中的道理,面对不同的平台,编译不同的结果。相对于Java的一次编译到处运行的跨平台性牺牲运行效率,C /C++的跨平台性则是牺牲编译时间以及编译的难度。这里的编译难度是指为适应不同平台而做的编译过程的调整,这个活 的难度可大可小,还不一定成功,视乎平台的兼容性以及支持。说到这里,难免会有人喷了:说什么跨平台性,这么复杂还不稳定!的确C/C++的跨平台性是有 局限性的,但是纵观当前的各种平台和系统,有哪家是不支持C/C++本地开发的?只是各自提供的底层API和编译条件不同而已,只需要调整一下C/C++ 的编译代码,通过编译即可运行,难道也不是一件美事?

4、编译并打包Java

把本地共享库放置到Java项目的指定目录,一般是libs文件件,Android的项目是libs/armeabi(armeabi 是对应的平台,后面会详讲),然后编译Java的代码即可运行!

NDK,(Native develop kit),本地开发工具包

NDK是Google为Android进行本地开发而放出的一个本地开发工具, 包括Android的Native API、公共库以及编译工具, 注意,NDK需要Android 1.5版本以上的支持哦。

按照上图的解说,NDK处在开发流程的编译环节,对,简单来说,NDK是JNI开发的一个扩展工具包!针对Android平台,其支持的设备型号繁多,单 单就设备的核心CPU而言,都有三大类:ARM、x86和MIPS,况且ARM又分为ARMv5和ARMv7等等,为何Android又能适配如此之多的 设备?接着JNI开发流程的话,利用NDK,我们可以针对不同的手机设备,编译出对应可运行的本地共享库了,至于如何使用NDK进行编译、开 发,我们留作下次再进行探讨。

SDK,(Standard Develop Kit),标准开发包

SDK是Google提供的Android标准开发工具包,里面包含了完整的 API文档,各Android版本的开发库,Android的虚拟机以及Android的打包工具等。众所周知,Android的应用开发语言是 Java,App的运行时是Delvik Runtime,属于JVM的改良版本,官方说Delvik VM更适用于移动设备。一般而言,由于Google的SDK提供了强大又完善的API,开发一般需求的应用,SDK足矣。然而前面已经说过,Java的运 行效率引发了不少问题,因而才有了JNI技术的存在,那SDK和NDK的关系是怎样的呢?见下图解说,可以说,NDK是SDK的一个补充。

SDK,JNI,NDK的开发流程

这个开发流程大致与JNI的开发流程差不多,下面我再详细说明一下每个环节:

SDK开发,编写Java代码,调用各种Android的API实现功能,编写含有native关键字的代码开始JNI;

JNI开发,按照 JNI编码规范,编写与Java交互的本地代码,一般就是数据类型的转换,把 C/C++的数据类转换成Java能识别的,或反过来。也因为这样子,我认为JNI其实就是Adapter,作为数据转换层而存在,具体JNI的一般操 作,我之后再分享;

C/C++开发,编码实现业务逻辑,或调用NDK提供的本地API或库,完成Android平台上特定功能的开发、封装;

NDK编译,编写.mk文件,编译调试,最后修改.mk文件,针对特定的平台(ARM/x86)做编译结果的优化;

最后就是SDK编译、打包,上真机调试了...

NDK、SDK以及JNI的关系的更多相关文章

  1. Android之NDK环境配置+JNI开发+so文件编译

    前言 这边Android作为日常记录,虽然破坏了文章队形~   最近人工智能挺火的,也稍微了解了一些库,比如关于视觉库openCV.要在安卓下调用这些C/C++库,需要用到JNI开发,在此把过程分享一 ...

  2. Android studio 使用NDK工具实现JNI编程

    前言: Android开发中常常会使用到第三方的.so库.在使用.so库的时候就要用到JNI编程.JNI是Java Native Interface的缩写.它提供了若干的API实现了Java和其它语言 ...

  3. Delphi使用android的NDK是通过JNI接口,封装好了,不用自己写本地代码,直接调用

    一.Android平台编程方式:      1.基于Android SDK进行开发的第三方应用都必须使用Java语言(Android的SDK基于Java实现)      2.自从ndk r5发布以后, ...

  4. NDK工具开发Jni,Android studio jni开发

    NDK工具开发JNI 对于JNI的作用,我这边就不详细说明了,百度google 有很多这样的介绍,这边着重详解AS使用NDK工具开发,调C的流程. 1,创建工程 2,创建native方法 //该类的路 ...

  5. Android JNI和NDK学习(06)--JNI的数据类型(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3094037.html 本文介绍JNI的数据类型.NDK中关于JNI数据类型的 ...

  6. NDK 与 JNI 的关系

    简介 JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码.JNI 是本地编程接口,Java和C/ ...

  7. Android Studio 中关于NDK编译及jni header生成的问题

    之前由于工作原因使用grails这个基于groovy的框架做项目,对groovy感觉很好. 基于groovy的gradle构建系统对我而言自然也是好的没得说. Android Studio 正式版出来 ...

  8. Ubuntu NDK配置与JNI demo

    NDK配置 1.下载最新版本NDK(android-ndk-r9d-linux-x86_64.tar.bz2) 下载网页:http://developer.android.com/tools/sdk/ ...

  9. ndk学习20: jni之OnLoad动态注册函数

    一.原理 当在系统中调用System.loadLibrary函数时,该函数会找到对应的动态库, 然后首先试图找到"JNI_OnLoad"函数,如果该函数存在,则调用它 JNI_On ...

随机推荐

  1. 【PRML读书笔记-Chapter1-Introduction】1.3 Model Selection

    在训练集上有个好的效果不见得在测试集中效果就好,因为可能存在过拟合(over-fitting)的问题. 如果训练集的数据质量很好,那我们只需对这些有效数据训练处一堆模型,或者对一个模型给定系列的参数值 ...

  2. Logcat 不显示日志的另一个原因. 跟cocos2dx关系不大.

    在Android真机调试时,如果在eclipse中看不到LogCat信息,提示是: $ adb logcat info: log device is empty! 原因是系统默认关闭了log,需要将其 ...

  3. android 应用层性能优化方案

    1.避免创建不必要的类对象 2.如果方法用不到成员变量,可以把方法声明为static,新能会提升15%到20% 3.避免使用getter和setter存取Filed,可以吧Field声明为public ...

  4. Java --计算百分比

    Learn From: http://blog.csdn.net/maggiehexu/article/details/6387636 方法一: public String getPercent(in ...

  5. tiny4412的中断资源连接关系示意图

    在tiny4412的设备树中可以发现,中断资源是以树的形式呈现的,下面是我画的一张图,大致描述了tiny4412上中断资源的连接关系. 可以到http://pan.baidu.com/s/1ge0sz ...

  6. shell的重定向

    >file  将file文件重定向为输出源,新建模式,可以将正确的结果输出到file文件 >>file 将file文件重定向为输出源,追加模式 <file  将file文件重定 ...

  7. Html5+css3+angularjs+jquery+webAPi 开发手机web(一)

    前言 随着浏览器的发展 HTML5+CSS3 的使用也越来越广泛,一直想学这个,想学那个折腾下来几乎没学到什么东西.工作经验告诉我,要掌握一门技术,就需要在项目中去磨练, 所以我就准备开发一个手机端的 ...

  8. Redis设计与实现-持久化篇

    redis数据库 默认16个数据库,每个数据库由一个redis.h/redisDb结构表示,此结构里的dict字典与expires字典,其中dict保存了该库所有键值对,此字典即为键空间:expire ...

  9. 关于WIndows内核自映射方案的通俗解释

    在一次操作系统课程上听老师说了这么一个有意思的东西,windows的自映射方案居然达到了把4K的页目录的线性地址“藏”在4M页表里的效果,感觉甚是奇特,于是乎就想着说怎么去算.光会算之后仍旧不满足,我 ...

  10. Scrum1.2--spring计划

    项目功能--深入分析  燃尽图