概念
JNI(Java Native Interface,Java本地接口),实现了Java和其他语言的交互(主要是C/C++),如:Java程序通过JNI调用C/C++编写的在Windows上运行的DLL动态链接库。

so(shared object,共享对象),Linux系统中的动态库,类似于Windows系统中的DLL。.so有时被直接调用,有时会参与到编译中。Android由Linux内核发展而来,因此在Android系统中也使用.so。

Android NDK(Android Native Development Kit),是Google提供的一系列的工具,简化通过JNI将C/C++动态库编译为.so库的过程。NDK集成了交叉编译器,并提供了相应的.mk文件隔离CPU、平台、ABI等差异,开发者只需要简单修改mk文件,执行编译脚本就可以创建.so。

NDK与JNI的关系:

JNI是Java与其他语言交互的机制,是Java语言自身的特性,与Android无关。

Android在框架上分为Application应用层、Application Framework应用框架层、libraries类库、Linux kernel内核。在应用框架层以及之上,使用Java语言进行开发;在此之下,Android自身的类库、驱动使用C/C++编写,再通过JNI提供接口给上层的Java调用。所以,Android框架使用了大量的JNI技术,让应用层的开发人员使用Java操控C/C++。

通常的Android开发都在应用框架层以及之上进行,但有时也需要对底层进行实现。显然,对底层的开发要复杂得多,NDK则是Google推出的帮助开发者通过C/C++编写应用的开发包,包含部分Android底层中常用的C/C++的头文件、库文件、说明文档和示例代码。

NDK只需要简单地编写几个.mk文件即可将c/c++代码编译为Android的java工程/Android手机可以识别、加载和运行的库或者应用程序。

Android.mk
ndk-build命令实际是执行了%NDK_PROJECT_PATH%/jni/Android.mk这个makefile文件,如果未配置%NDK_PROJECT_PATH%环境变量,则需要定位到工程目录。同时,待编译的.c和编译配置文件Android.mk也需要位于名为jni的目录下。

Android.mk是NDK编译的配置文件,其中定义了需要编译的.c文件、依赖的.h头文件、编译出的so库名等等信息,是使用NDK进行编译的关键。

为什么使用NDK

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

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

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

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

mk文件中的语法:

1.LOCAL_PATH

这个变量用于给出当前文件的路径。你必须在Android.mk的开头定义。例如:

LOCAL_PATH := $(call my-dir)

2.LOCAL_MODULE

这是你模块的名字,它必须是唯一的,而且不能包含空格。你必须在包含任一的$(BUILD_XXXX)脚本之前定义它。模块的名字决定了生成文件的名字。

3.LOCAL_MODULE_FILENAME

默认的情况下,编译生成的文件名为lib$(LOCAL_MODULE).so/a在使用的此变量后,会用此变量的名来覆盖系统默认的生成文件名。例如:

LOCAL_MODULE := foo-version-1

LOCAL_MODULE_FILENAME := foo生成的文件名为libfoo.so/a

4.LOCAL_SRC_FILES

要直接传递给编译器的源代码文件列表。只要列出要传递给编译器的文件即可,因为编译系统自动为你计算依赖

5.LOCAL_C_INCLUDES

可选的路径列表,相对于NDK的根目录,当编译所有的源文件(C、C++、或者汇编)时将被追加到搜索路径中
例如:
LOCAL_C_INCLUDES:=sources/foo
或者
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../foo

6.LOCAL_EXPORT_CFLAGS

定义这个变量用来记录C/C++编译器标志集合

  include $(CLEAR_VARS)

LOCAL_MODULE := foo

LOCAL_SRC_FILES := foo/foo.c

LOCAL_EXPORT_CFLAGS := -DFOO=1

include $(BUILD_STATIC_LIBRARY)

  定义-DFOO 为1

7.import-module

此函数用于按模块名称来查找和包含模块的 Android.mk 文件。 典型的示例如下所示:

$(call import-module,<name>)

在此示例中,构建系统在 NDK_MODULE_PATH 环境变量所引用的目录列表中查找以 <name> 标记的模块,并且自动包括其 Android.mk 文件。

8.include

include可Android多以这样的形式出现,如:include $( CLEAR_VARS),include $(BUILD_SHARED_LIBRARY).其实这个include可以理解成"执行"的意思,那么执行什么呢?当然是看后边的宏了.

宏CLEAR_VARS表示清除一些变量.

宏BUILD_SHARED_LIBRARY表示生成共享库,即生成.so文件,它负责收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。

因此include $(BUILD_SHARED_LIBRARY)就是指定在/system/lib/目录下生成一个lib$(LOCAL_MOUDULE).so文件,同样类型的宏如下:

CLEAR_VARS                                             清除LOCAL_xxx变量
BUILD_SHARED_LIBRARY                     在/system/lib/目录下生成lib$(LOCAL_MOUDULE).so文件
BUILD_STATIC_LIBRARY                         生成lib$(LOCAL_MOUDULE).a文件
BUILD_EXECUTABLE                               在/system/bin/目录下生成可执行文件
BUILD_PACKAGE                                      编译成一个apk文件

NDK jni mk文件 so文件 巴啦啦 初体验的更多相关文章

  1. android NDK jni下的c文件 Unresolved inclusion

    原因是在eclipse编辑环境中没有找到对应的include中的文件.解决方法是将包含该文件的include目录作为新的linked folder加入工程中.具体方法如下:1. 右击工程->Ne ...

  2. eclipse上ndk环境的搭建&&so文件的生成&&jni文件的调用

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

  3. Android NDK 初探,生成so文件以及调用so文件方法

    因为最近业务上涉及安全的问题 然后有一些加密解密的方法和key的存储问题 本来想存储到手机里面,但是网上说一般敏感信息不要存储到手机Sdcard上 而且我这个如果从网络建立通信获取的话,又太耗时,所以 ...

  4. JNI读取assets资源文件

    源自:http://www.rosoo.net/a/201112/15459.html assets目录底下的文件会被打包到一个apk文件里,这些资源在安装时他们并没被解压,使用时是直接从apk中读取 ...

  5. NDK 通过java调用so文件

    首先我们来看so文件的来源 1. 自己写.c文件,然后生成so库 2. 引用别人的静态库,或者动态库来生成新的jni调用库. 我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通 ...

  6. Android - JNI加入标准C++文件

    JNI加入标准C++文件 本文地址: http://blog.csdn.net/caroline_wendy 其余參考: http://blog.csdn.net/caroline_wendy/art ...

  7. android studio使用ndk,jni随记

    1.下载ndk(会下载到sdk目录下) 2.配置 3.配置build.gradle(app) android { defaultConfig { ndk { moduleName "JniD ...

  8. Android NDK Application.mk(中文翻译)

    作者:阿宝 更新:2016-08-31 来源:彩色世界(https://blog.hz601.org/2016/07/26/android-NDK-application-mk/index.html) ...

  9. Andorid——ubuntu下的 NDK / JNI

    之前一直有接触源代码里面的JNI体系,知道个大概,仅仅管调进了哪个C/C++的接口,如今记录学习下. 撰写不易,转载请注明出处:http://blog.csdn.net/jscese/article/ ...

随机推荐

  1. 跟我学SpringCloud | 第三篇:服务的提供与Feign调用

    跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...

  2. java源码解析之String类(四)

    /* * 返回指定字符第一次出现的字符串内的索引 */ public int indexOf(int ch) { return indexOf(ch, 0); } /* * 返回指定字符第一次出现的字 ...

  3. 【简易bat脚本】启动java程序

    前置条件:path中添加了JAVAHOME配置了java环境变量 1.新建txt文本文件 2.粘贴以下内容 @echo off set path=%path%;.;java -classpath &q ...

  4. PowerDesigner16.5 有用地址

    http://blog.csdn.net/keenweiwei/article/details/32720427

  5. python算法与数据结构-队列(44)

    一.队列的介绍 队列的定义:队列是一种特殊的线性表,只允许在表的头部(front处)进行删除操作,在表的尾部(rear处)进行插入操作的线性数据结构,这种结构就叫做队列.进行插入操作的一端称为队尾,进 ...

  6. 字节跳动Java研发面试99题(含答案):JVM+Spring+MySQL+线程池+锁

    JVM的内存结构 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1. Java虚拟机栈:线程私有:每个方法在执行的时候会创建一个栈帧,存储了局部变量表, ...

  7. 恢复云数据库MySQL的备份文件到自建数据库遇到的报错

    报错信息 : 恢复云数据库MySQL的备份文件到自建数据库,自建数据库版本5.6.36. 按照阿里云文档操作,启动数据库报错 -- :: [ERROR] /application/mysql/bin/ ...

  8. PyCharm2018 汉化&激活

    一.汉化 将下载好的resources_cn_PyCharm_2018.1_r2.jar 放入pycharm 的lib 目录中,启动app即可 下载链接: https://pan.baidu.com/ ...

  9. 5分钟快速部署PESCMS TEAM 团队任务管理系统开发版

    所在的公司也经历过小团队的发展,为了高效率,通常都是面对面交流,很多时候事情谈论过后不久就已经淡忘了.而且工作任务不能全局观察,成员之间基本上都要主动去询问,效率反而低下.所以今天就介绍一款中小团队的 ...

  10. POJ 1113:Wall(凸包)

    http://poj.org/problem?id=1113 Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 346 ...