概念
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. (Demo分享)利用JavaScript(JS)做一个可输入分钟的倒计时钟功能

    利用JavaScript(JS)实现一个可输入分钟的倒计时钟功能本文章为 Tz张无忌 原创文章,转载请注明来源,谢谢合作! 网络各种利用JavaScript做倒计时的Demo对新手很不友好,这里我亲手 ...

  2. Electron为文件浏览器创建图标(三)

    在前面的文章中,请看之前文章,我们已经完成了使用 electron做文件浏览器这么一个应用,现在我们需要为应用创建图标操作.为应用创建图标以后,我们就可以从计算机中与其他应用区分开来,如果我们自己会做 ...

  3. 【JAVA NIO】java NIO

    本文是博主深入学习Netty前的一些铺垫,之前只是使用Netty,用的很粗暴,导包,上网找个DEMO就直接用,对Netty中的组件了解并不深入. 于是再此总结下基础,并对一些核心组件作如下记录: 1. ...

  4. http协议之状态码

    =================状态码,状态文字======================== 状态码:用来反应服务器的响应状态 状态文字:是用来说明状态码的. 状态码:可以分为这5个大的部分 - ...

  5. 跟我学SpringCloud | 第九篇:服务网关Zuul初

    SpringCloud系列教程 | 第九篇:服务网关Zuul初探 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散 ...

  6. 小代介绍Spring Boot

    想要获取更多文章可以访问我的博客 - 代码无止境. 小代很顺利的完成了陈BOSS交代给他搭建Spring Boot示例程序的任务.但是小代是一个乐于学习的程序员,他通过一番学习总结了一篇简单介绍Spr ...

  7. [Python学习]错误篇二:切换当前工作目录时出错——FileNotFoundError: [WinError 3] 系统找不到指定的路径

    REFERENCE:<Head First Python> ID:我的第二篇[Python学习] BIRTHDAY:2019.7.13 EXPERIENCE_SHARING:解决切换当前工 ...

  8. Drools规则引擎-memberOf操作

    场景 规则引擎技术讨论2群(715840230)有同学提出疑问,memberOf的使用过程中如果,memberOf之后的参数不是集合也不是数组,而是格式如"1,2,3,4"的字符串 ...

  9. 【动态规划法(DP)】-C++

    360百科定义: 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.20世纪50年代初美国数学家R.E.Bell ...

  10. <a>标签 IOS 安卓 亲测有效

    一.普通链接 <a href="http://www.baidu.com">百度</a> 二.邮件链接 1.标签最简式 <a href="m ...