Android JNI开发系列(二)HelloWorld

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

入门HelloWorld

新建项目

  • Configure your new project部分选中 Include C++ Support 复选框

  • Next

  • 正常填写所有其他字段并完成向导接下来几个部分

  • 在向导的Customize C++ Support 部分,您可以使用谢列选项自定义项目:

    • C++ Standard : 使用下拉列表选择使用的C++标准。选择Toolchain Defalut 会使用默认的CMake设置。

    • Exception Support : 如果您希望启用对C++异常处理的支持,请选中该复选框,Android Studio 会将 -fexception标志添加到模块级别build.gradle 文件的cppFlag中,Gradle会将其传递到CMake.

    • Runtime Type Information Support: 如果您希望支持RTTI,请选中该复选框,如果启用Android Studio会将**-frtti标志添加到模块级别build.gradle** 文件的cppFlag中,Gradle会将其传递到CMake.

  • finish

项目结构

  • cpp 组

    您可以找到属于项目的所有原生源文件、标头和预构建库。对于新项目,Android Studio 会创建一个示例 C++ 源文件 native-lib.cpp,并将其置于应用模块的 src/main/cpp/ 目录中。本示例代码提供了一个简单的 C++ 函数 stringFromJNI(),此函数可以返回字符串“Hello from C++”。要了解如何向项目添加其他源文件,请参阅介绍如何创建新的原生源文件的部分。

  • External Build File :

    您可以找到 CMake 或 ndk-build 的构建脚本。与 build.gradle 文件指示 Gradle 如何构建应用一样,CMake 和 ndk-build 需要一个构建脚本来了解如何构建您的原生库。对于新项目,Android Studio 会创建一个 CMake 构建脚本 CMakeLists.txt,并将其置于模块的根目录中。要详细了解此构建脚本的内容,请参阅介绍如何创建 Cmake 构建脚本的部分。

构建过程

Gradle 调用您的外部构建脚本 CMakeLists.txt。 CMake 按照构建脚本中的命令将 C++ 源文件例如 native-lib.cpp 编译到共享的对象库中,并命名为 libnative-lib.so,Gradle 随后会将其打包到APK 中。

创建 CMake 构建脚本

如果您的原生源文件还没有 CMake 构建脚本,则您需要自行创建一个并包含适当的 CMake 命令。CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeLists.txt。本部分介绍了您应包含到构建脚本中的一些基本命令,用于在创建原生库时指示 CMake 应使用哪些源文件。

要创建一个可以用作 CMake 构建脚本的纯文本文件,请按以下步骤操作

  • 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
  • 右键点击 您的模块 的根目录并选择 New > File。
  • 输入“CMakeLists.txt”作为文件名并点击 OK。

要指示 CMake 从原生源代码创建一个原生库,请将 cmake_minimum_required()add_library() 命令添加到您的构建脚本中:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.//指定可用的CMake构建脚本版本cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
# 指定需传入三个参数(函数库名称,库类型,依赖源文件相对路径)add_library( # Sets the name of the library.native-lib# SHARED 动态链接库  STATIC 静态链接库 Sets the library as a shared library.SHARED # 相对路径 Provides a relative path to your source file(s).src/main/cpp/native-lib.cpp )# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.# 用于定位NDK中的库
# 需要传入两个参数(path变量、ndk库名称)
find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.# 指定CMake查询库的名称,即在ndk 开发包中查询liblog.so函数库,将其路径赋值给log-liblog )# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.# 指定关联到原生库的库target_link_libraries( # Specifies the target library.# 指定目标库,与善变的函数名保持一致native-lib# Links the target library to the log library# included in the NDK.# 链接的库,根据log-lib变量对应liblog.so函数库${log-lib} )

NOTE:

  • 使用 add_library() 向您的 CMake 构建脚本添加源文件或库时,Android Studio 还会在您同步项目后在 Project 视图下显示关联的标头文件。不过,为了确保 CMake 可以在编译时定位您的标头文件,您需要将 include_directories() 命令添加到 CMake 构建脚本中并指定标头的路径:
# Specifies a path to native header files.
include_directories(src/main/cpp/include/)
  • 将 find_library() 命令添加到您的 CMake 构建脚本中以定位 NDK 库,并将其路径存储为一个变量。您可以使用此变量在构建脚本的其他部分引用 NDK 库。以下示例可以定位 Android 特定的日志支持库并将其路径存储在 log-lib 中:
find_library( # Defines the name of the path variable that stores the# location of the NDK library.log-lib# Specifies the name of the NDK library that# CMake needs to locate.log )
  • 为了确保您的原生库可以在 log 库中调用函数,您需要使用 CMake 构建脚本中的 target_link_libraries() 命令关联库:
find_library(...)# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.native-lib# Links the log library to the target library.${log-lib} )
  • NDK 还以源代码的形式包含一些库,您在构建和关联到您的原生库时需要使用这些代码。您可以使用 CMake 构建脚本中的 add_library() 命令,将源代码编译到原生库中。要提供本地 NDK 库的路径,您可以使用 ANDROID_NDK 路径变量,Android Studio 会自动为您定义此变量。

以下命令可以指示 CMake 构建 android_native_app_glue.c,后者会将 NativeActivity 生命周期事件和触摸输入置于静态库中并将静态库关联到 native-lib:

add_library( app-glueSTATIC${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )
  • 添加预构建库与为 CMake 指定要构建的另一个原生库类似。不过,由于库已经预先构建,您需要使用 IMPORTED 标志告知 CMake 您只希望将库导入到项目中:
add_library( imported-libSHAREDIMPORTED )

然后,您需要使用 set_target_properties() 命令指定库的路径,如下所示。

某些库为特定的 CPU 架构(或应用二进制接口 (ABI))提供了单独的软件包,并将其组织到单独的目录中。此方法既有助于库充分利用特定的 CPU 架构,又能让您仅使用所需的库版本。要向 CMake 构建脚本中添加库的多个 ABI 版本,而不必为库的每个版本编写多个命令,您可以使用 ANDROID_ABI 路径变量。此变量使用 NDK 支持的一组默认 ABI,或者您手动配置 Gradle 而让其使用的一组经过筛选的 ABI。例如:

add_library(...)
set_target_properties( # Specifies the target library.imported-lib# Specifies the parameter you want to define.PROPERTIES IMPORTED_LOCATION# Provides the path to the library you want to import.imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
  • 为了确保 CMake 可以在编译时定位您的标头文件,您需要使用 include_directories() 命令,并包含标头文件的路径:
include_directories( imported-lib/include/ )
  • 要将预构建库关联到您自己的原生库,请将其添加到 CMake 构建脚本的 target_link_libraries() 命令中:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )

构建应用时,Gradle 会自动将导入的库打包到 APK 中。您可以使用 APK 分析器验证 Gradle 将哪些库打包到您的 APK 中。如需了解有关 CMake 命令的详细信息,请参阅 CMake 文档。

新建Demo时候遇到的坑

  • CMakeList.txt

    add_libary() 脚本,报错,如果写了新的Cpp/C文件,rebuld不会提示并生成,直接报错在该节点首行,

    应先在对应目录新建Cpp/C文件,再引入

  • 注意修改 target_link_libraries 下的 target Libary

转载于:https://my.oschina.net/caipeng/blog/2243624

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sublime text3安装js提示的插件

今天安装Sublime Text3的js插件,在网上查了很多资料,为了方便以后看,写一个安装插件的总结和方法。 要安装js相关的插件,就要先安装一个Package Control(插件管理器)的插件,通过这个插件再去安装…

SPI接口详细介绍

1. 概述 SPI Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。常规只占用四根线,节约了芯片管脚,PCB的布局省空间。现在越来越多的芯片集成了这种通信协议&#xff0…

驻扎博客园

今天把之前hexo里的一些文章全部转移到博客园了,之后就在博客园写点东西,记录一些生活的琐事。为什么要移至博客园呢?其实很简单,这边可以和一些同意从事前端的小伙伴一起互动。技术还是需要多讨论的,希望之后能多更新…

H.264 Profile、Level、Encoder三张简图

H.264有四种画质级别,分别是BP、EP、MP、HP: 1、BP-Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;   2、EP-Extended profile:进阶画质。支持I/P/B/SP/SI 帧&…

require.js学习记录

1、简介 官方对requirejs的描述:RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will impro…

iOS-AFNetworking参数和多文件同时上传【多文件上传】

1. 前言 在项目开发中,我们经常需要上传文件,例如:上传图片,上传各种文件,而有时也需要将参数和多个文件一起上传,不知道大家的项目中遇到了没有,我在最近的项目中,就需要这样的一个…

智能音箱 之 平台方案简介

智能音箱,被认为是物联网时代的入口,在去年成为了各大厂商争相投入的风口。在当今互联网时代,它不仅仅是一台单纯的音乐播放器,在其背后支撑的 AI 技术才是整个产品的核心,也是各大公司觊觎物联网入口的最根本原因。经…

Linux Kconfig及Makefile学习

内核源码树的目录下都有两个文档 Kconfig (2.4版本是Config.in)和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了 所属目录源文档相关的内核配置菜单。在内核配置make menuconfig时,从K…

Linux编程 23 shell编程(结构化条件判断 命令if -then , if-then ... elif-then ...else,if test)...

一.概述 在上一篇里讲到了shell脚本,shell按照命令在脚本中出现的顺序依次进行处理,对于顺序操作已经足够了,但许多程序要求对shell脚本中的命令加入一些逻辑流程控制,这样的命令通常叫做 结构化命令。 1.1 使用if - then语句 --最…

Scala-Spark digamma stackoverflow问题

这两天在用spark做点击率的贝叶斯平滑,参考雅虎的论文进行了一番尝试。 先上代码: 1 # click_count, show_count # this method takes time2 def do_smooth(data_list):3 import scipy.special as sp4 a, b, i 1.0, 1.0, 05 da, db a, b6 …

IIS接口详细介绍

1. 概述 I2S Inter-IC Sound Integrated Interchip Sound IIS,是飞利浦在1986年定义(1996年修订)的数字音频传输标准,用于数字音频数据在系统内器件之间传输,例如编解码器CODEC、DSP、数字输入/输出接口、ADC、DAC…

UVA - 10934 Dropping water balloons(装满水的气球)(dp)

题意:有k个气球,n层楼,求出至少需要多少次实验能确定气球的硬度。气球不会被实验所“磨损”。 分析: 1、dp[i][j]表示第i个气球,测试j次所能确定的最高楼层。 2、假设第i-1个气球测试j-1次所确定的最高楼层是a, 若第i个…

继承进阶

先讲一个例子&#xff1a; #老师有生日&#xff0c;怎么组合哪&#xff1f; class Birthday: # 生日def __init__(self,year,month,day):self.year yearself.month monthself.day dayclass Teacher: # 老师<br>def __init__(self,name,birth):self.name nameself.b…

PCM接口详细介绍--TDM方式

1. 概述 PCM = Pulse Code Modulation 是通过等时间隔(即采样率时钟周期)采样将模拟信号数字化的方法。图为4 bit 采样深度的PCM数据量化示意图: PCM数字音频接口,说明接口传输的音频数据是通过PCM方式采样得到的,区别于PDM形式;IIS传输的也是PCM类型数据,属于其一个特…

网站同源策略

所谓"同源"指的是"三个相同"&#xff1a;协议&#xff0c;域名&#xff0c;端口。 举例来说&#xff0c;http://www.example.com/dir/page.html这个网址&#xff0c;协议是http://&#xff0c;域名是www.example.com&#xff0c;端口是80&#xff08;默认端…

Kconfig文件结构(图文)简介

1 Kconfig和Makefile 毫不夸张地说&#xff0c;Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件。基本上&#xff0c;Linux 内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。Kconfig和Makefile就好似一个城市的地图&#xff0c;地图引导我们去 认识一…

PDM接口介绍

1. 概述 PDM Pulse Density Modulation是一种用数字信号表示模拟信号的调制方法。 PDM则使用远高于PCM采样率的时钟采样调制模拟分量&#xff0c;只有1位输出&#xff0c;要么为0&#xff0c;要么为1。因此通过PDM方式表示的数字音频也被称为Oversampled 1-bit Audio。相比P…

js正则学习分享

http://www.cnblogs.com/rubylouvre/archive/2010/03/09/1681222.htmlhttp://www.cnblogs.com/tylerdonet/p/4262251.html //正整数 /^[0-9]*[1-9][0-9]*$/; //负整数 /^-[0-9]*[1-9][0-9]*$/; //正浮点数 /^(([0-9]\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9])|([0-9]*[1…

Linux系统下UDP发送和接收广播消息小例子

分类&#xff1a; 网络通信 2013-01-07 10:54 1336人阅读 评论(6) 收藏 举报 [cpp] view plaincopyprint?// 发送端 #include <iostream> #include <stdio.h> #include <sys/socket.h> #include <unistd.h> #include <sys/types.h>…

Kaggle 泰坦尼克

入门kaggle&#xff0c;开始机器学习应用之旅。 参看一些入门的博客&#xff0c;感觉pandas&#xff0c;sklearn需要熟练掌握&#xff0c;同时也学到了一些很有用的tricks&#xff0c;包括数据分析和机器学习的知识点。下面记录一些有趣的数据分析方法和一个自己撸的小程序。 1…