参考:https://developer.android.com/studio/projects/add-native-code.html#link-gradle

使用Android Studio 2.2以上版本、Android插件 Gradle 2.2.0以上版本,可以将C/C++代码编译成native库,然后Gradle将库打包到APK中。Java代码可以通过JNI(Java Native Interface)调用native库中的函数。

本文所用环境为为Android Studio 2.2.2。

  • 安装NDK

用Android Studio集成的SDK Manager安装NDK、CMake和LLDB。其中CMake是编译工具,LLDB是调试工具。

  • 新建工程

勾选Include C++ Support

到下面这一步时,有三个选项:

C++ Standard:选择要用的C++标准,我的列表里有Toolchain Default和C++ 11,由于对C++标准没要求,我直接选Default,也就是编译工具(默认为CMake)的默认配置。

Exceptions Support:如果勾选,则编译时支持C++异常处理。Android Studio会在module对应的build.gradle中的cppFlags中添加 -fexceptions,这个cppFlags会被Gradle传递给CMake。

Runtime Type Information Support:如果勾选,则支持RTTI,Android Studio会在module对应的build.gradle中的cppFlags中添加 –frtti。

注:RTTI,(Run-Time Type Identification),通过RTTI, 程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。

全部勾选,点击Finish完成工程的创建。

工程新建完成后,可以看到如上的目录,其中:

cpp中包含了所有项目中使用的native源码文件、头文件和预编译库。native-lib.cpp是Android Studio自动生成的一个sample文件,放在module的src/main/cpp中。

External Build Files中包含了CMake或ndk-build的编译脚本。CMakeLists.txt是Android Studio自动生成的一个CMake脚本,放在module的根目录中。

  • 编译并运行

点击Run,编辑并运行这个工程,APP呈现如下的界面:

下面就是编译和运行这个APP时发生的事情:

1.Gradle调用外部的编译脚本CMakeLists.txt

2.CMake执行编译脚本中的命令,将C++源文件(native-lib.cpp)编译成共享对象库(libnative-lib.so),Gradle再将这个so库打包到APK中。

生成的libnative-lib.so在module对应的build\intermediates\cmake\debug\obj中,如下图所示:

用APK Analyser可以看到APK中打包了libnative-lib.so库:

Build->Analyze APK..,如下:

3.运行时,MainActivity通过System.LoadLibrary()加载native库,然后库中的native方法就可以用了。下面是MainActivity中的代码。

 

  • 添加C/C++文件到工程

1.在module的cpp文件夹中,右键,new->C++ Class或者C/C++ Source File。

新建完成后,不会马上在Android目录结构中看到文件,打开新建的文件,会提示需在编译文件中添加该文件,并且同步工程。

2.在CMakeLists.txt中,添加对新建cpp文件的配置。

3.点击Sync Now,同步完成后,就可以在Android目录结构下看到新建的文件了。

  • CMakeLists.txt

1.CMake的编译脚本必须命名为CMakeLists.txt

如果不是,就会报错,如下:

2.CMakeLists.txt最好放在module的根目录

其实放在任意目录都可以,但是文件中声明的C/C++文件路径,都是相对于编译脚本文件所在的目录。

3.CMake默认将库文件命名为:

但是在使用时,仍然使用library-name导入就行了。

4.CMake 命令:

(1)cmake_minimum_required(VERSION 3.4.1) - 指定CMake最低版本

(2)add_library(...) - 声明库名称、类型、源码文件
(3)include_directories() - 指定关联的头文件目录
(4)find_library() - 定位某个NDK库,并将其路径存储为一个变量,可以在其他地方用这个变量引用NDK库
(5)target_link_libraries() - 将NDK库链接到native库中,这样native库才能调用NDK库中的函数
5.将NDK目录下的源码编译到native库中:
其中,ANDROID_NDK是AndroidStudio自动定义好的变量。
6.添加其他预编译库
需要用IMPORT标志,告诉CMake,只需要引用这个预编译库(不需要进行编译)。
 

然后用set_target_properties()指定库的路径。

其中ANDROID_ABI这个变量列出了NDK支持的所有ABI(Application Binary Interface),用这个变量可以让CMake引用多个ABI对应的库文件。

当然,还要指定头文件路径:

最后,用target_link_libraries()将预编译库链接到native库中。

NDK 笔记(一)的更多相关文章

  1. Android NDK笔记

    目录 Android NDK笔记 AOSP Android repository Android SDK / SDK Tools NDK cmake && ninja lldb adb ...

  2. NDK笔记(二)-在Android Studio中使用ndk-build

    前面一篇我们接触了CMake,这一篇写写关于ndk-build的使用过程.刚刚用到,想到哪儿写哪儿. 环境背景 Android开发IDE版本:AndroidStudio 2.2以上版本(目前已经升级到 ...

  3. android NDK 笔记

    *************************************************华丽的分割线********************************************* ...

  4. NDK笔记(二)-在Android Studio中使用ndk-build(转)

    前面一篇我们接触了CMake,这一篇写写关于ndk-build的使用过程.刚刚用到,想到哪儿写哪儿. 环境背景 Android开发IDE版本:AndroidStudio 2.2以上版本(目前已经升级到 ...

  5. NDK(三方库引入、Mk文件)

    NDK笔记-----第三方库引入 一.字符操作: 1 二.NDK*(JNI)对象操作: 2 1.C++调用java对象 3 三.Android.mk说明: 3 四.Application.mk说明 3 ...

  6. Android JNI&NDK编程小结及建议

    前言 由于网上关于JNI/NDK相关的知识点介绍的比较零散而且不具备参照性,所以写了这篇JNI/NDK笔记,便于作为随时查阅的工具类型的文章,本文主要的介绍了在平时项目中常用的命令.JNI数据类型.签 ...

  7. NDK开发_笔记0

    自谷歌搜索退出中国以来,谷歌对全球第二大市场中国的态度一直保持冷淡.可是北京时间12月8日,谷歌2016开发者大会在北京召开,同时专门针对中国的谷歌开发者网站已经上线:https://develope ...

  8. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  9. 《android开发艺术探索》读书笔记(十四)--JNI和NDK编程

    接上篇<android开发艺术探索>读书笔记(十三)--综合技术 No1: Java JNI--Java Native Interface(java本地接口),它是为了方便java调用C. ...

随机推荐

  1. 原生Ajax

    使用原生Ajax 验证用户名是否被注册 创建出注册信息: <h1>注册信息</h1><input type="text" name="txt ...

  2. Linux进程学习

    进程与进程管理: 清屏:system("clear"); //#include <signal.h> 进程环境与进程属性: 什么是进程:简单的说,进程就是程序的一次执行 ...

  3. Introduction to graph theory 图论/脑网络基础

    Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...

  4. Mysql完全手册(笔记二,使用数据与性能优化)

    一.使用数据 1.使用变量 MySQL也可以让我们以用户自定义的变量来存储select查询的结果,以便在将来select查询中使用.它们只会在客户会话期间存在,但是它们提供一个方便有效的方法来连接查询 ...

  5. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  6. Not Hello World

    通常对于一门语言的学习,一般都是以"Hello,World!"开始的.但对于汇编语言的学习,输出这句话并不容易,首先得了解寄存器等硬件知识. 汇编语言要得以运行,首先要讲源文件编译 ...

  7. openssl+前端jsrsa签名+后端nodejs验签

    内容如标题所示,总体分为三个部分: 一.win10下安装openssl,然后通过openssl工具生成RSA的公钥和私钥 (1)win10下安装openssl需要的工具有:VS2013,Perl,na ...

  8. SpringMVC注解汇总(二)-请求映射规则

    接上一节SpringMVC注解汇总-定义 讲到Httpy请求信息 URL路径映射 1)普通URL路径映射 @RequestMapping(value={"/test1", &quo ...

  9. android studio 中移除module和恢复module

    一.移除Android Studio中module 在Android Studio中想要删除某个module时,在Android Studio中选中module,右键发现没有delete,如图: An ...

  10. 关于repaint(重绘)和reflow( 回流)

    repaint就是重绘,reflow就是回流.repaint主要是针对某一个DOM元素进行的重绘,reflow则是回流,针对整个页面的重排 严重性: 在性能优先的前提下,性能消耗 reflow大于re ...