最近由于项目的需要,使用到了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. ExtJs TreePanel 使用帮助

    tree :树 node:节点 1.全部展开 tree.expandAll(); 2.全部收缩 tree.collapseAll(); 3.得到父节点 node.parentNode 4.判断是否有父 ...

  2. PIN码计算锦集

    1. 腾达,C8:3A:35开头的MAC有效~network路由,MAC有效~以及00B00C开头的MAC有效之外的请您自己发现算法..这里只公布三个MAC地址算法,其余也可以算~这里就不公布出来了. ...

  3. 搭建WebRtc环境

    0.前言 这次的需求,准备做的是一个类似与QQ视频一样的点对点视频聊天.这几天了解了一些知识后,决定使用HTML5新支持的WebRtc来作为视频通讯.客户端使用支持HTML5浏览器即可.服务器段需要提 ...

  4. [引用]SQLServer占CPU100%

    程序猿是如何解决SQLServer占CPU100%的   文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 ...

  5. Unity 资源管理与更新

    当你在 工程目录下的 Asset 文件夹中放置一个文件时(电脑上的文件夹,不是 Unity 界面中的文件夹),Unity会自动检测到一个新的文件被添加(Unity会不停地检查Assets文件夹中的内容 ...

  6. 用vuejs写了一个酷狗的webApp

    这几天在学习vueJS,学了半个月,觉得是不是该写点什么呢?于是 .脑子一抽,仿了一个酷狗的webapp. 项目截图: 由于是单页应用,切换路由时音乐不会停止,算是一个小亮点吧. 技术栈: vuejs ...

  7. 哀悼我的第一次"创业"经历

    下周考完最后一科,大学四年时光基本上算是落下帷幕,剩下的就只是整整毕业设计了.如果按照正常的节奏,这个学期应该能够搞完毕业设计的2/3,但无奈还在广州的一家公司里面实习,没有多少时间弄,得拖到3月了. ...

  8. CSS布局 -- 左右定宽,中间自适应

    左右定宽,中间自适应 有几种方法可以实现 改变窗口大小看看? 方案一: 左右设置绝对定位,定宽,中间设置margin-left  margin-right 查看 demo <!DOCTYPE h ...

  9. Linq查询简介

    查询是一种从数据源检索数据的表达式. 查询通常用专门的查询语言来表示. 随着时间的推移,人们已经为各种数据源开发了不同的语言:例如,用于关系数据库的 SQL 和用于 XML 的 XQuery. 因此, ...

  10. 【C#】属性(Attribute)

    如果程序员是猫,你是哪只猫? 这个是我一直都很喜欢的一个技术,不是很麻烦,也不是很难理解,和反射配合起来,只有你想不到没有做不到的用途(夸张了哈). 运用范围 程序集,模块,类型(类,结构,枚举,接口 ...