对于Android应用开发,大部分情况下我们使用Java就能完整地实现一个应用。但是在某些情况下,我们需要借助C/C++来写JNI本地代码。比如,在使用跨平台的第三方库的时候;为了提升密集计算性能的时候(这种情况下往往还可能会直接使用汇编语言)。因此,这里我将为大家介绍如何给其它开发者创建可供使用的静态库或动态库。而应用开发者如何去连接这些生成的静态库或动态库。由于现在Android Studio已经比较成熟,因此以下描述将基于Android Studio的目录布局。

在Android Studio的一个项目工程下,会有一个app文件夹,这个文件夹主要存放我们编写应用的所有代码以及相关其它资源。如果我们需要写JNI,那么就需要在这个目录下创建jni文件夹。jni文件夹里必须包含Android.mk文件、Application.mk文件以及你所要编译的源文件。下面我们先给出编译生成提供给第三方开发者使用的静态库与动态库的Android.mk文件内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 编译后生成的模块名,在Java端使用System.loadLibrary加载模块的的时候直接用此名
LOCAL_MODULE := my_blocks # LOCAL_SRC_FILES用于添加源文件(可以是.c,.cpp,.s等)
LOCAL_SRC_FILES := my_block_test.c
LOCAL_SRC_FILES += my_blocks_data.c
LOCAL_SRC_FILES += my_runtime.c # 条件预编译,如果当前架构为ARMv7以下的架构,则定义MY_NO_CSWAP这个宏
ifeq ($(TARGET_ARCH_ABI),armeabi)
LOCAL_CFLAGS := -DMY_NO_CSWAP=1
endif # 连接系统编译出的静态库
LOCAL_STATIC_LIBRARIES := cpufeatures
LOCAL_STATIC_LIBRARIES += ld.gold LOCAL_LDLIBS := -llog # 用于生成动态库
# include $(BUILD_SHARED_LIBRARY) # 用于生成静态库
include $(BUILD_STATIC_LIBRARY) $(call import-module,cpufeatures)

然后,我们把上述编译脚本中所列出的my_block_test.c、my_blocks_data.c以及my_runtime.c这三个源文件放在jni目录下即可编译。

最后,用Android JNI编译器工具——ndk_build编译完之后就可在生成的obj目录下看到my_blocks.a文件了。在Unix/Linux下,.a表示静态库文件;.so表示动态共享库文件。

下面我们将创建另一个工程,这个工程将构建最终可执行的应用。其Android.mk文件描述如下:

LOCAL_PATH := $(call my-dir)

### 以下这段用于预构建我们将要连接的已存在的静态库或动态库 ###

include $(CLEAR_VARS)

# 我们将连接已编译好的my_blocks模块
LOCAL_MODULE := my_blocks # 填写源文件名的时候,要把静态库或动态库的文件名填写完整。
# $(TARGET_ARCH_ABI)/ 表示将不同架构下的库文件存放到相应架构目录下
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmy_blocks.a # LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmy_blocks.so # 用于预构建静态库(后面可被连接)
include $(PREBUILT_STATIC_LIBRARY) # 用于预构建动态库(后面可被连接)
# include $(PREBUILT_SHARED_LIBRARY) # 这里要注意的是,对于一次预构建只能预构建动态库,要么是静态库,两者不能共存 ### 以下内容用于描述编译当前工程的源代码 ### include $(CLEAR_VARS) LOCAL_MODULE := mytest LOCAL_SRC_FILES := test.c LOCAL_STATIC_LIBRARIES := cpufeatures
LOCAL_STATIC_LIBRARIES += ld.gold # 连接我们前面声明好的静态库
LOCAL_STATIC_LIBRARIES += my_blocks # 连接我们前面声明好的动态库
# LOCAL_SHARED_LIBRARIES += my_blocks LOCAL_LDLIBS := -llog # 将此模块构建为动态库
include $(BUILD_SHARED_LIBRARY) $(call import-module,cpufeatures)

下面我们来看一下这个工程jni的目录结构内容:

在arm64-v8a、armeabi等每个架构名目录下,都要包含有我们在第一个工程中生成出来的静态库或动态库文件,并且要与架构名相一致。比如一下是arm64-v8a下的内容:

然后,我们需要编辑Application.mk文件,如下所示:

# 使用当前NDK编译器所支持的所有处理器架构
APP_ABI := all # 使用LLVM Clang 3.6编译器工具链
NDK_TOOLCHAIN_VERSION=clang3.6 # 开启C11标准,外加GNU语法扩展
APP_CFLAGS += -std=gnu11 # 启用Blocks语法
APP_CFLAGS += -fblocks

最后,我们在Java端只需加载我们当前所要执行的动态库模块即可,不需要关心前一个工程所生成的、用于给当前JNI模块所使用的动态库或静态库。

Android NDK生成及连接静态库与动态库的更多相关文章

  1. android开发 NDK 编译和使用静态库、动态库 (转)

    在eclipse工程目录下建立一个jni的文件夹 在jni文件夹中建立Android.mk和Application.mk文件 Android.mk文件: Android提供的一种makefile文件, ...

  2. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  3. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  4. [转]Linux下用gcc/g++生成静态库和动态库(Z)

    Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10|  分类: linux |  标签:链接库  linux  g++  gcc  |举报|字号 订阅     ...

  5. Linux-Gcc生成和使用静态库和动态库详解

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  6. iOS 静态库和动态库的区别&静态库的生成

    linux中静态库和动态库的区别 一.不同 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函 ...

  7. 【转】Linux下gcc生成和使用静态库和动态库详解

    一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...

  8. Linux下GCC生成和使用静态库和动态库【转】

    本文转载自:http://www.cppblog.com/deane/articles/165216.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本 ...

  9. Linux下的静态库与动态库的生成与调用

    静态库与动态库 静态函数库 这类库的名字一般是libxxx.a,xxx为库的名字.利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行 ...

随机推荐

  1. Flask--init和run启动研究---xunfeng巡风实例篇

    第一: 首先在view目录下的__init__.py文件定义好 (1) Flask实例 : app = Flask(__name__) (2) 数据库实例 Mongo = Conn.MongoDB(a ...

  2. oracle导出多CSV文件的靠谱的

    oracle导出多CSV文件的问题 ---------------------------------------------------------------------- 用ksh脚本从orac ...

  3. [Vijos] 弱弱的战壕

    描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒 ...

  4. 【NOIP模拟】数字对(RMQ,二分)

    题意:小H是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n). 这个特 ...

  5. 线程&线程池

    线程 进程和线程: 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 注意:两个都是过程 线程一个特点: 一个进程中,多个线程共享资源 线程和进程区 ...

  6. PAT (Advanced Level) 1039. Course List for Student (25)

    map会超时,二分吧... #include<iostream> #include<cstring> #include<cmath> #include<alg ...

  7. Fractal---POJ2083(dfs)

    http://poj.org/problem?id=2083 一道我认为有点恶心的dfs       刚开始没有初始化  用G++交  一直TLE  后来用了C++竟然是wa   那这肯定是我的问题了 ...

  8. [Bzoj1015][JSOI2008]星球大战starwar(并查集)(离线处理)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 6849  Solved: 3204[Submit ...

  9. oracle dtrace for linux

    https://docs.oracle.com/cd/E37670_01/E37355/html/ol_config_dtrace.html#

  10. 关于maven多个模块的build顺序 [INFO] Reactor Build Order

    对于一个maven项目,如果有多个模块,那么它们的执行顺序是什么样的呢? 在执行mvn操作的时候,你可以看到如下信息,这个便是maven的build顺序 那么maven是如何决定顺序的呢?如下: 在多 ...