参考: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. idea 插件的使用 进阶篇

    CSDN 2016博客之星评选结果公布    [系列直播]零基础学习微信小程序!      "我的2016"主题征文活动   博客的神秘功能 idea 插件的使用 进阶篇(个人收集 ...

  2. BZOJ1500[NOI2005]维修数列

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  3. redis3.0配置文件详解

    redis.conf #redis.conf # Redis configuration file example. # ./redis-server /path/to/redis.conf #### ...

  4. [LeetCode] Count Primes 质数的个数

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  5. go database/sql sql-driver/mysql 操作

    这里使用的是github.com/Go-SQL-Driver/MySQL, 所以需要下载一个github.com/Go-SQL-Driver/MySQL 引入 database/sql 和 githu ...

  6. Android——Adapter

    Adapter——本身只是一个接口.Adapter是将数据绑定到UI界面上的桥接类.Adapter负责创建显示每个项目的子View和提供对下层数据的访问. 数据适配器作用:把复杂的数据(数组.链表.数 ...

  7. Oracle的一些操作

    . 创建用户 Create user 用户名 identified by "密码"; 例如:create user ghc_ez identified by "ghc_2 ...

  8. XPatchLib 对象增量数据序列化及反序列化器 For .Net

    在日常的软件开发和使用过程中,我们发现同一套系统的同一配置项在不同的客户环境中是存在各种各样的差异的.在差异较为分散时,如何较好的管理这些差异,使得维护过程能够更加安全和快速,一直在这样那样的困扰着开 ...

  9. Javascript两个感叹号的用法(!!)

    var foo; alert(!foo);//undefind情况下或者null,一个感叹号返回的是true; alert(!goo);//undefind情况下,一个感叹号返回的也是true; 但是 ...

  10. JavaScript系列文章:变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...