




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】AndroidStudio中通过CMake使用NDK并编译自定义库和添加预编译库
Note:这篇文章是基于AndroidStudio3.01版本的,NDK是R16。step1:创建一个包含C++的项目其他默认就可以了。C++Standard指定编译库的环境,其中ToolchainDefault使用的是默认的CMake环境;C++11也就是C++环境。两种环境都可以编库,至于区别,后续会跟进,当前博文使用的是CMake环境。ExceptionsSupport
如果选中复选框,则表示当前项目支持C++异常处理,如果支持,在项目Module级别的build.gradle文件中会增加一个标识-fexceptions到cppFlags属性中,并且在so库构建时,gradle会把该属性值传递给CMake进行构建。RuntimeTypeInformationSupport
同理,选中复选框,项目支持RTTI,属性cppFlags增加标识-frtti切换到project模式,生成的目录的结构如下:3、认识CMakeLists.txt构建脚本文件CMakeLists.txt文件用于配置JNI项目属性,主要用于声明CMake使用版本、so库名称、C/CPP文件路径等信息,下面是该文件内容:cmake_minimum_required(VERSION3.4.1)CMake最小版本使用的是3.4.1。add_library()配置so库信息(为当前当前脚本文件添加库)native-lib这个是声明引用so库的名称,在项目中,如果需要使用这个so文件,引用的名称就是这个。值得注意的是,实际上生成的so文件名称是libnative-lib。当Run项目或者build项目是,在Module级别的build文件下的intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main下会生成相应的so库文件。SHARED这个参数表示共享so库文件,也就是在Run项目或者build项目时会在目录intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main下生成so库文。此外,so库文件都会在打包到.apk里面,可以通过选择菜单栏的Build->AnalyzeApk...*查看apk中是否存在so库文件,一般它会存放在lib目录下。src/main/cpp/native-lib.cpp构建so库的源文件。STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用。SHARED:动态库,会被动态链接,在运行时被加载。MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接。头文件也可以配置头文件路径,方法是(注意这里指定的是目录而非文件):下面的配置实际上与自定义的JNI项目(自定义的so库)没有太大关系。find_library()这个方法与我们要创建的so库无关而是使用NDK的Apis或者库,默认情况下Android平台集成了很多NDK库文件,所以这些文件是没有必要打包到apk里面去的。直接声明想要使用的库名称即可(猜测:貌似是在Sytem/libs目录下)。在这里不需要指定库的路径,因为这个路径已经是CMake路径搜索的一部分。如示例中使用的是log相关的so库。log-lib这个指定的是在NDK库中每个类型的库会存放一个特定的位置,而log库存放在log-lib中log指定使用log库target_link_libraries()如果你本地的库(native-lib)想要调用log库的方法,那么就需要配置这个属性,意思是把NDK库关联到本地库。native-lib要被关联的库名称${log-lib}要关联的库名称,要用大括号包裹,前面还要有$符号去引用。实际上,我们可以自己创建CMakeLists.txt文件,而且路径不受限制,只要在build.gradle中配置externalNativeBuild.cmake.path来指定该文件路径即可。add_subdirectory可以执行子路径的CMakeLists.txt添加自定义的C++库mathlib创建源文件我的项目名称为OpenCVTest,所以右键这个项目点击New->Module,然后选AndroidLibrary,输入库的名称MathLib,然后Finish,系统就会生成对应的模块,并构建好初始的目录树。系统将库命名为MathLib,但是目录树中还是小写的mathlib。这个时候系统会自动在顶级settings.gradle添加对于这个新模块的include语句。并且在模块目录下构建好了初始的build.gradle。
现在我们开始创建自己的C++库,首先右键mathlib目录下的src/main,然后选择New->Directory,输入cpp并确定。这个目录就是我们要创建的库的源文件的位置。
右键add,点击New->C/C++SourceFile,输入add.cpp,并选中Createanassociatedheader。
在.cpp文件中定义好一个简单的加法函数,并在.h文件中添加好对应声明。
add.cpp将源文件关联到构建系统中我们用CMake来构建C++库,然后CMake又要和gradle结合,在AndroidStudio里面协作管理C++和Java的代码。
我们在模块mathlib的根目录下创建一个名为CMakeLists.txt的文件,写入
set可以自定义变量。这里定义生成so文件的目录
set_target_properties命令的意思是设置目标的一些属性来改变它们构建的方式。这个命令中设置了add的ARCHIVE_OUTPUT_DIRECTORY属性。也就是改变了输出路径。
add_custom_command命令是自定义命令。命令中把头文件也复制到了distribution_DIR中。
target_include_directories,它对创建的库设置include路径,针对目标来设置,可以避免与其他库的冲突,并且此时对自定义的库设置好了此路径后,后续导入这个库就不需要再次设置了。但对于预构建的库,就需要设置,稍后会有详细讲解。
接下来我们在模块mathlib的build.gradle中的defaultConfig{}中添加如下语句:
这里arguments是编译参数,而targets则是相比于add_subdirectory更高权限的方法。一般来说可以把它删去,即默认构建所有目标。
然后在android{}最后添加如下语句,将CMakeLists.txt关联起来。
C++库已经创建好了,接下来就要在主模块中使用它了。为了使用自定义C++库,我们需要一个中间人,它从Android本身的Java程序中获取请求,然后使用我们的C++库中的函数计算得到结果,并将数据传回Android本身的Java程序中。创建一个中间文件native-math.cpp在app/CMakeLists.txt加上这个自定义库的引用
在模块app的局部build.gradle中,像之前一样添加好对应的语句:defaultConfig{}中:其中ndk指定abi平台
ABI(Applicationbinaryinterface)应用程序二进制接口。不同的CPU与指令集的每种组合都有定义的ABI(应用程序二进制接口),一段程序只有遵循这个接口规范才能在该CPU上运行,所以同样的程序代码为了兼容多个不同的CPU,需要为不同的ABI构建不同的库文件。当然对于CPU来说,不同的架构并不意味着一定互不兼容。armeabi设备只兼容armeabi;
armeabi-v7a设备兼容armeabi-v7a、armeabi;
arm64-v8a设备兼容arm64-v8a、armeabi-v7a、armeabi;
X86设备兼容X86、armeabi;
X86_64设备兼容X86_64、X86、armeabi;
mips64设备兼容mips64、mips;
mips只兼容mips;
接着在src/main/java/*/MainActivity.java中的MainActivity类下面,加载库,以及设置好对应的方法声明:然后就可以在onCreate方法中使用这个C++库定义的函数,在Java中对应的函数了
最后别忘了在项目中添加模块的依赖关系才可以正常运行这个AndroidApp。右键项目OpenCVTest,选择OpenModuleSettings。选择app->Dependencies,添加Moduledependency,选择mathlib,确定即可添加OpenCV库的支持导入OpenCV进项目从OpenCV的官网将OpenCV4Android3.4下载下来,解压到某个目录。
点击AndroidStudio的File->New->ImportModule,然后选择路径为OpenCV-android-sdk/sdk/java,确定。并在导入之后,修改build.gradle中的SDK版本。
在OpenModuleSettings中添加模块的依赖关系,使app依赖openCVLibrary340。现在已经可以在.java文件中看得到OpenCV的自动补全了。配置OpenCV的C++预构建库把包含文件夹OpenCV-android-sdk/sdk/native/jni/include和预构建库文件夹OpenCV-android-sdk/sdk/native/libs也复制到项目的distribution中。由于之前已经在添加C++库时修改了app的build.gradle,所以这个步骤现在不需要再执行了。由于OpenCV是预构建库,所以没有编译的过程,因此模块openCVLibrary320中不需要添加CMakeLists.txt等。我们直接在app模块中根目录下的CMakeLists.txt导入OpenCV的库即可。需要注意的是.so使用SHARED,.a使用STATIC。注意:预构建库:so文件和.a文件必须copy在src/main/jniLibs这个目录,才
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO/IEC 24760-2:2025 EN Information security,cybersecurity and privacy protection - A framework for identity management - Part 2: Reference architecture and requirements
- 2025秋统编版三年级(2024)新教材语文上册《手术台就是阵地》练习题及答案
- 编织品耐候性测试技术改进考核试卷及答案
- 稀土离子浮选回收工艺考核试卷及答案
- 兴趣点地理信息采集员5S管理考核试卷及答案
- 建筑五金制品制作工三级安全教育(公司级)考核试卷及答案
- 信息技术考试题及答案
- 服务心理学(第四版)课件 项目三 任务二 转变角色意识
- 马克思主义基本原理核心考点综合测试卷
- 银行押韵员面试题及答案
- 玻璃体切除手术护理查房
- 第三届全国大学生未来农业律师大赛试题
- 审批及决策流程管理制度
- 泌尿系结石 课件
- 物业投标书样本
- 【组织沟通障碍及其对策探究-以A企业为例12000字(论文)】
- 殡葬礼仪服务投标方案(技术方案)
- 血液灌流治疗癌症的原理与前景
- 2024年四川能投宜宾市叙州电力限公司招聘高频考题难、易错点模拟试题(共500题)附带答案详解
- -广告制作报价单-明细
- 屁屁辅助脚本
评论
0/150
提交评论