• NDK、SDK以及JNI的关系


         最近由于项目的需要,使用到了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编译、打包,上真机调试了...

  • 相关阅读:
    迷你版jQuery——zepto核心源码分析
    zepto.js 源码解析
    zepto.js swipe实现触屏tab菜单
    zepto.js 处理Touch事件
    Zepto 使用中的一些注意点(转)
    判断js对象的数据类型,有没有一个最完美的方法?
    html 5 本地数据库(Web Sql Database)核心方法openDatabase、transaction、executeSql 详解
    HTML5本地存储——Web SQL Database
    js事件监听器用法实例详解-注册与注销监听封装
    10 个非常有用的 AngularJS 框架
  • 原文地址:https://www.cnblogs.com/l2rf/p/4310390.html
Copyright © 2020-2023  润新知