NDK开发入门教程
AndroidStudio用Cmake方式编译NDK代码(cmake配置.a库)
AndroidStudio⽤Cmake⽅式编译NDK代码(cmake配置.a库)1.cmake是什么?CMake是⼀个跨平台的安装()⼯具,可以⽤简单的语句来描述所有平台的安装(编译过程)。
他能够输出各种各样的makefile或者project⽂件,能测试所⽀持的C++特性,类似UNIX下的automake。
⾕歌从AndroidStudio2.2以上就添加了Cmake⽅式来编译NDK代码,并从NDK例⼦看出,默认编译的⽅式就是cmake⽅式。
2.⾕歌官⽅的⽤cmake⽅式编译NDK的教程⾕歌从AndroidStudio2.2以上就添加了Cmake⽅式来编译NDK代码,并从NDK例⼦看出,默认编译的⽅式就是cmake⽅式。
如果您希望向现有项⽬添加原⽣代码,请执⾏以下步骤:1. 并将其添加到您的 Android Studio 项⽬中。
如果您已经拥有原⽣代码或想要导⼊预构建的原⽣库,则可以跳过此步骤。
2. ,将您的原⽣源代码构建到库中。
如果导⼊和关联预构建库或平台库,您也需要此构建脚本。
如果您的现有原⽣库已经拥有CMakeLists.txt构建脚本或者使⽤ ndk-build 并包含构建脚本,则可以跳过此步骤。
3. 提供⼀个指向您的 CMake 或 ndk-build 脚本⽂件的路径,。
Gradle 使⽤构建脚本将源代码导⼊您的 Android Studio 项⽬并将原⽣库(SO ⽂件)封装到 APK 中。
配置完项⽬后,您可以使⽤从 Java 代码中访问您的原⽣函数。
要构建和运⾏应⽤,只需点击 Run 。
Gradle 会以依赖项的形式添加您的外部原⽣构建流程,⽤于编译、构建原⽣库并将其随 APK ⼀起封装。
创建新的原⽣源⽂件要在应⽤模块的主源代码集中创建⼀个包含新建原⽣源⽂件的cpp/⽬录,请按以下步骤操作:1. 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
2. 导航到您的模块 > src,右键点击 main ⽬录,然后选择 New > Directory。
mediacodec ndk编程
mediacodec ndk编程
MediaCodec NDK编程是指使用Android NDK(Native Development Kit)来开发使用MediaCodec API的应用程序。
MediaCodec API是Android中用于音视频编解码的API,它提
供了硬件加速的编解码功能,可以在开发中实现音视频数据的压缩、解压、编码和解码等操作。
在NDK编程中使用MediaCodec API可以有以下步骤:
1. 配置Android.mk文件:在NDK项目的Android.mk文件中
添加依赖库的链接,例如:LOCAL_LDLIBS += -lmediandk
2. 调用MediaCodec API:在NDK的C/C++代码中调用MediaCodec API来实现音视频编解码的操作,例如:创建编
解码器、配置编解码参数、调用start()方法来启动编解码器等。
3. 使用Buffer进行数据传输:通过设置输入输出缓冲区来传
输音视频数据,音频数据通过AudioBufferInfo来描述,视频
数据通过VideoBufferInfo来描述。
4. 处理编解码结果:通过获取编解码器的输出缓冲区来处理编解码结果,可以获得解码后的音视频数据,通过回调或写入文件等方式进行处理。
需要注意的是,MediaCodec API的使用需要对编解码相关的
知识有一定的了解,并且需要通过Android NDK来进行开发。
掌握C/C++编程语言和Android NDK开发技术的基础,对于进行MediaCodec NDK编程是非常有帮助的。
NDK入门 生成.so文件
关于生成.so文件:利用NDK生成.so库,使用,so库进行JNI调用。
NDK是什么,作用是什么,网上有很多关于NDK的信息,这里就不再赘述;当我们安装好Cygwin后测试保证可以正常使用,接下来我们需要的就是安装NDK,网址下载最新的版本;(我的版本是r8版本)下载好压缩包后将NDK解压;我们找到Cygwin的安装路径,找到.bash_profile这个文件;我的环境位于下,这里需要注意的是千万不要用记事本一类的阅读文件打开,不然会死的很惨的,当时没有注意,用记事本打开后,配置好环境发现无法输出NDK的相关信息,为此纠结了很久,所以提醒大家少走弯路~这里需要用到UE打开此文件(UE 全名UltraEdit),在打开之后提示是否转换为DOS格式么,选择否;(选择是的话Cygwin中查找NDK的信息也不报错也不输出关于NDK的路径信息,为什么也找不到相关资料,原因是否在这里也不是特别清楚);打开.bash_profile文件后在文章最后填这么一段代码:第一句是你自己安装NDK的路径;(千万别照抄,后果很严重)!第二句是输出NDK的信息;这里NDK可以随便取名字,简短最好,更不要包含任何中文或者空格信息,不然会报错;保存.bash_profile文件后再次重新启动Cygwin;在Cygwin中输入#cd $NDK;如果显示出信息(也就是你的NDK安装路径),恭喜你,你的NDK也安装成功了;接下来我们就测试一下,最好使用NDK自带的例子生成.so文件:1>打开Cygwin软件后,进入到你的NDK自带例子程序安装路径;我的是2>执行下面的命令# $NDK/ndk-build稍等一下,会出现此时,你的.so库就产生了;该.so库会在samples文件夹下一个lib的文件夹内(lib文件目录是自动产生的),打开lib 文件夹后出现,打开此文件夹.so库就安静的躺在里面;如何使该.so库可被eclipse调用生成安卓可执行文件.apk后面详细讲述;。
AndroidNDK交叉编译C++代码生成.so共享库详细步骤
AndroidNDK交叉编译C++代码⽣成.so共享库详细步骤1 在需要调⽤模板库的⽂件前包含头⽂件:#include <iostream>#include <vector>此时编译可能不过,需要在android.mk⽂件内添加:LOCAL_C_INCLUDES := /home/administrator/android-ndk-r5b/sources/cxx-stl/stlport/stlport (ndk安装路径下的stl库)2 在 mk ⽂件前加⼊:APP_STL := stlprot_static (模板库以静态库的⽅式添加)....LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog \/home/administrator/android-ndk-r5b/sources/cxx-stl/stlport/libs/armeabi/libstlport_static.a我的Android.mk⽂件中的内容为:LOCAL_PATH := $(call my-dir)LOCAL_C_INCLUDES += external/stlport/stlportLOCAL_C_INCLUDES += bionicLOCAL_C_INCLUDES += bionic/libstdc++/includeLOCAL_SHARED_LIBRARIES := libstlportGXPM_LIB_DIR := ../../../common/GoxceedPMinclude $(CLEAR_VARS)#$(GXPM_LIB_DIR)/minidb/minilzo/minilzo.c \GXPM_SRC_FILES := \$(GXPM_LIB_DIR)/zlib/adler32.c \$(GXPM_LIB_DIR)/zlib/compress.c \$(GXPM_LIB_DIR)/zlib/crc32.c \$(GXPM_LIB_DIR)/zlib/deflate.c \$(GXPM_LIB_DIR)/zlib/gzio.c \$(GXPM_LIB_DIR)/zlib/inffast.c \$(GXPM_LIB_DIR)/zlib/inflate.c \$(GXPM_LIB_DIR)/zlib/inftrees.c \$(GXPM_LIB_DIR)/zlib/trees.c \$(GXPM_LIB_DIR)/zlib/uncompr.c \$(GXPM_LIB_DIR)/zlib/zutil.c \$(GXPM_LIB_DIR)/lz4/lz4.c \$(GXPM_LIB_DIR)/lz4/lz4frame.c \$(GXPM_LIB_DIR)/lz4/lz4hc.c \$(GXPM_LIB_DIR)/lz4/xxhash.c \$(GXPM_LIB_DIR)/minilzo/minilzo.c \$(GXPM_LIB_DIR)/minidb/bitmap.c \$(GXPM_LIB_DIR)/minidb/buddy.c \$(GXPM_LIB_DIR)/minidb/compressor.cpp \$(GXPM_LIB_DIR)/minidb/compr_lz4.cpp \$(GXPM_LIB_DIR)/minidb/compr_lz77.cpp \$(GXPM_LIB_DIR)/minidb/compr_lzo.cpp \$(GXPM_LIB_DIR)/minidb/compr_zlib.cpp \$(GXPM_LIB_DIR)/minidb/db.cpp \$(GXPM_LIB_DIR)/minidb/hash.c \$(GXPM_LIB_DIR)/minidb/io.cpp \$(GXPM_LIB_DIR)/minidb/map.c \$(GXPM_LIB_DIR)/textcode_convert.c \LOCAL_SRC_FILES := \$(GXPM_SRC_FILES) \gomedia.cppLOCAL_C_INCLUDES := \$(LOCAL_PATH)/../../../common/GoxceedPM/zlib/include \$(LOCAL_PATH)/../../../common/GoxceedPM/lz4 \$(LOCAL_PATH)/../../../common/GoxceedPM/minilzo \$(LOCAL_PATH)/../../../common/GoxceedPM/minidb \$(LOCAL_PATH)/../../../common/GoxceedPM/core \ $(LOCAL_PATH)/../../../common/GoxceedPM \ LOCAL_LDLIBS := -llogLOCAL_MODULE := gomediainclude $(BUILD_SHARED_LIBRARY) Application.mk:APP_ABI := allAPP_PLATFORM := android-8APP_STL := stlport_staticAPP_CPPFLAGS := -fpermissiveaa。
android入门教程
8步教你打开Android之门 NDK入门教程这是一篇Android NDK开发的入门教程,在这一教程结束后,你将创建你自己的项目,从Java代码简单地调用原生C语言代码。
前不久我们为大家介绍过在MyEclipse 8.6上搭建Android开发环境,本文为一篇外文翻译,我们将介绍如何学习安装 Android NDK 并开始使用它。
在这一教程结束后,你将创建你自己的项目,从 Java 代码简单地调用原生 C 语言代码。
教程细节技术:Android SDK、NDK、C 语言难度:进阶预计完成时间:60-90 分钟先决经验在我们开始之前,我们需要先花点时间了解一下这一教程的难度。
它的标记是“进阶”。
之所以标为“进阶”是因为我们这些作者想要确保你符合以下要求:你有Java和C语言经验。
你能适应命令行操作。
你知道如何了解你的 Cygwin、awk 和其他工具的版本。
你能适应 Android Development。
你有一个有效的 Android 开发环境(本文撰写时,笔者使用的是 Android 2.2)你使用 Eclipse 或者可以将 Eclipse 的指导步骤轻松应用于你自己的 IDE 上。
就算你并不满足这些条件,我们当然也欢迎你阅读这一教程,不过你可能在某些步骤遇到困难,如果你满足了以上条件这些困难就会轻易解除。
也就是说,即使你认为自己是个移动开发老手,使用 NDK 依然很容易碰到困难和麻烦。
请注意你可能要自行排查故障才能让一切正常运转于你的开发系统中。
本教程提供完整的样例项目的开源代码下载。
何时使用 NDK 的说明好,如果你正在阅读这篇教程,你也许已经在考虑在你的 Android 项目中使用 NDK 了。
不过,我们想要花点时间讨论一下 NDK 为什么那么重要、何时该使用它,以及——同等重要的,何时不该使用它。
总的来说,只有当你的应用程序真的是个处理器杀手的时候你才需要使用 NDK。
也就是说,你设计的算法要利用 DalvikVM 中所有的处理器资源,而且原生运行较为有利。
NDK运行环境配置
点击cygwin安装包,进行安装,进入如下界面:选择第三个,安装本地安装包,点击下一步,进入如下制定安装路径然后下一步会搜索到本地安装包的目录,如果没有,自己指定,下一步安装后,会有一个警告提示,不管,直接确定,出现如下点击那个DEVEL后面的default点击编程install然后一直下一步,开始安装到这里安装完毕,是否选择在桌面创建一个快捷图标,或者在开始里面添加快捷启动项到此,linux模拟器安装完成NDK安装先启动一次cygwin!!他会自动创建一些文件,然后在命令行输入Gcc -v 如果出现如下图表示安装成功!!然后到cygwin的安装目录。
进入home文件夹,找见自己机器的名称的文件夹后,将NDK 的开发包,放进这个目录内(NDK的目录可以任意指定),复制完成后,打开目录里面的.bash_profile这个文件在最后一行,添加上环境变量名称=/cygdrive/你的NDK开发包所在路径例如:NDK_ROOT=/cygdrive/f/android/NDK/android-ndk-r4然后再加上一句export 你的环境变量名称配置完成后,重启cygwin在命令提示框,输入Cd $你的环境变量名称,例如cd $NDK_ROOT 注意大小写然后,会出现如下提示这样表示进入了你的NDK开发包根目录,现在可以试着编译一个NDK的例子,在NDK开发包下的samples文件夹下的第一个例子,helloJNI通过命令行CD命令,进入到helloJNI工程下面的JNI文件夹中进入这个目录然后直接打一个$你的环境变量名/ndk-build例如$NDK/ndk-build然后会出现如下运行结果然后查看工程目录下面的libs文件会多出一个armeabi文件夹,里面会有libhello-jni.so的库文件然后就可以将这个工程导入到eclipse中,就可以进行测试了。
AndroidSDKPDKNDK详解
AndroidSDKPDKNDK详解昨天⼀个同事问我 PDK,NDK,SDK都是做什么的,什么意思。
之前听到过这⼏个词,感觉⾃⼰能够理解,但是发现要⽐较清晰的给她解释才发现⾃⼰的理解可能还不是很到位,带着疑问查了查资料,结合⾃⼰的理解写下来。
其实这个三个词应该是在软件开发领域通⽤的,它们的全称分别为SDK(Software Development Kit),PDK(Platform DevelopmentKit),NDK(Native Development Kit),我们可以从它们的⽤途以及针对的⼈群来理解⼀下。
1.SDK 软件开发套件⼀般平台都会发布⾃⼰的SDK,SDK包含该平台为应⽤程序开发⼈员提供的开发⼯具,主要是所有公开API的集合,应⽤程序开发⼈员可以借助SDK中的API快速的进⾏应⽤的开发。
Android SDK针对所有应⽤开发⼈员开放,下载ADT查看sdk⽬录如下:sdk├──add-ons├──build-tools├──extras├── platforms├──platform-tools└──toolsSDK⽂件⽬录解释:1) add-ons 这⾥保存⼀些附加库,例如GoogleMaps2) build-tools 这⾥放的是Android的⼀些重要的编译⼯具,⽐如aapt、aidl、逆向调试⼯具dexdump和编译脚本dx等3) extras 存放的是⼏次⼤的升级添加的新功能相关的static library,如android-v4,android-v7,android-v134) platforms 存放的是平台真正的SDK,其中会根据APILevel来区分SDK的版本,命名规则android-APILevel,如android 4.4 SDK的⽂件夹名称为android-20,其⽂件⽬录如下:├──android.jar├── build.prop├──data├── framework.aidl├── sdk.properties├──skins├── source.properties├── templates└── uiautomator.jar该⽬录下主要⽂件android.jar为该版本framework的主要⽂件,包括class,图⽚等;data⽬录下为系统的资源⽂件,包括字符串资源,fonts 字体库⽂件,activity broadcast的action记录,intent的category,widget的列表等内容;skins⽬录为Android模拟器的⽪肤资源;templates⽬录下为创建Android⼯程默认模板,包括AndroidManifest.xml,⽂件,launch图标等;5) platform-tools 此⽬录主要放置的是平台⼯具,如adb, fastboot, sqlite3等6) tootls 这个⽬录中有⽐较重要的调试⼯具,如ddms(包括⼀些截图),Android模拟器的主程序emulator,traceview性能优化⼯具, UI控件扫描⼯具uiautomatorviewer,UI层级显⽰⼯具hierarchyviewer,代码混淆⼯具proguard,ant编译脚本,代码缺陷扫描⼯具lint等,这个⽬录下也有个templates⽬录,简单看了下不太明⽩是⼲什么⽤的,有兴趣的可以了解⼀下。
Android JNI NDK
编写Android NDK程序步骤
在编写上面代码时应注意如下两点:
Android JNI接口设计
AndroidN DK应用程序的接口实际上就 是在JNI(Java Native Interface)规范中定 义的接口。JNI规范中定义了Java调用动 态链接库(*.dll或*.so文件,由于 Android是Linux内核的操作系统,因此 只有*.so文件)的约定。这里的接口就 是指函数,包括函数名称、函数参数个 数、函数参数类型及函数返回值的类型。
Android JNI接口设计
举个简单的例子,看一下hello-jni.c文件中的c语言函数, 代码如下: Jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JN IEnv* env, jobject thiz) { return (*env)->NewStringUTF(env, “Hello from JNI!”); } 上面的代码中的函数从表面上看只是一个普通的c语言 函数,但这个函数和普通的c语言函数有如下3点不 同:
Android NDK简介
NDK由如下几部分组成: 提供了一套工具集,这套工具集可以将 c/c++源代码生成本地代码。 用于定义NDK接口的C头文件(*.h)和 实现这些接口的库文件。 一套编译系统。可以通过非常少的配置 生成目标文件。
下载和安装Android NDK
Android NDK开发和JNI开发
第九章NDK开发与JNI开发9.1 NDK开发我们先来说说Android SDK (Android Software Development Kit), 即Android软件开发工具包。
可以说只要你使用Java去开发Android这个东西就必须用到。
他包含了SDK Manager 和AVD Manage。
对于android系统的一些开发版本的管理以及模拟器管理。
而NDK (Native Development Kit)跟SDK差不多的是他也是一个开发工具包。
用他开发C/C++是很方便的。
他有一个强大的编译集合。
9.1.1 NDK产生的背景Android平台从诞生起,就已经支持C、C++开发。
众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。
但这并不等同于“第三方应用只能使用Java”。
在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。
不过,Google也表示,使用原生SDK编程相比Dalvik虚拟机也有一些劣势,Android SDK文档里,找不到任何JNI方面的帮助。
即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍。
比如程序更加复杂,兼容性难以保障,无法访问Framework API,Debug难度更大等。
开发者需要自行斟酌使用。
于是NDK就应运而生了。
NDK全称是Native Development Kit。
NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。
NDK将是Android平台支持C开发的开端。
9.1.2 为什么使用NDK1、代码的保护。
NDK环境配置(包括最新版)及简单实用
如我的为NDK=/cygdrive/E/Android/android-ndk-r7b export NDK
注:"NDK"这个名字随便起,以后经常用别太长
②证
重启cygwin,输入:cd $NDK
可进入ndk对应目录说明设置OK。
生成项目中native方法,编译成so文件。
在eclipse中新建一个android项目,例如testNdk,最低适应版本选1.5以上,以为NDK支持的最低版本就是1.5,我这里选的2.1。
在项目中新建Jni类,示例代码如下:
publicclassJni {
publicnativeintshowRusult(inta,intb);
intaa= jni.showRusult(4, 87);
Log.v("test","aa: "+aa);
setTitle(jni.showRusult(5,8)+"");
}
将项目编译一下,让系统生成类的class文件,一会要用到。
4
打开Cygwin,进入项目的bin目录下,
如果之前已经编译过了,那系统应该已经在项目bin目录中生成了classes文件夹,进入这个文件夹。
输入命令$NDK/ndk-build,出现如下结果,说明编译成功。
现在可以看到,在sources/testNdk文件夹下,生成了libs、obj两个文件夹,将libs文件夹整个复制到android项目中即可。
二、使用
当然,首先需要搭建好android环境,包括SDK、ADT、eclipse等,具体方法我就不讲了,网上有很多。
JNI开发与调试流程
JNI开发与调试流程JNI(Java Native Interface)是一种允许Java应用程序与其他编程语言(如C++、C等)进行交互的技术。
开发和调试JNI需要遵循一定的流程,下面是一个关于JNI开发与调试流程的详细介绍。
一、JNI开发流程:1. 确定接口:首先确定需要在Java应用程序和C/C++代码之间建立的接口。
要确定接口的数据类型、方法参数、方法名称和返回值类型等。
2. 编写Java代码:在Java应用程序中编写调用JNI接口的Java代码,包括声明native方法和使用System.loadLibrary(加载动态链接库。
3. 编写C/C++代码:在C/C++环境中编写实现JNI接口的C/C++代码,实现Java代码中声明的native方法。
这些C/C++代码需要与操作系统和编译器兼容。
4. 生成动态链接库:将C/C++代码编译成动态链接库,以供Java应用程序调用。
具体的编译过程会因操作系统和编译器而有所不同。
5. 测试与调试:通过调用Java应用程序来测试JNI接口的正确性和性能。
可以使用调试器等工具来定位和修复问题。
二、JNI调试流程:1. 准备调试环境:在开发JNI之前,首先需要准备好调试环境。
这包括安装并配置Java JDK、C/C++编译器和调试器等。
2.设置调试参数:在调试过程中,需要设置一些调试参数,例如设置断点、参数传递、环境变量等。
这样可以更方便地跟踪和调试代码。
3. 启动调试器:使用调试器启动Java应用程序,并指定要调试的JNI代码。
调试器会在Java代码和C/C++代码之间切换,方便跟踪代码执行流程。
4.设置断点:在需要调试的代码行上设置断点,以便在程序执行到该行时暂停程序的执行,可以逐行查看代码执行情况。
5.单步调试:在断点处暂停后,使用调试器提供的单步调试功能,可以逐行查看代码的执行情况,包括变量的值、函数的返回值等。
6.观察变量:在调试过程中,可以观察和监视变量的值,以便查找代码中的错误或问题。
ndk的使用流程
ndk的使用流程NDK(Native Development Kit)是Android提供的一个开发工具包,用于开发C/C++库,并将其集成到Android应用程序中。
NDK的使用流程可以分为以下几个步骤。
第一步,安装配置NDK。
首先需要下载NDK,可以从Android官方网站或者Android Studio的SDK Manager中下载安装。
安装完成后,需要配置NDK的环境变量,以便在命令行中可以直接使用NDK提供的工具。
第二步,创建NDK项目。
可以使用Android Studio创建一个新的NDK项目,或者将NDK集成到现有的Android项目中。
在项目的build.gradle文件中,需要添加NDK的配置信息,包括NDK的版本和需要编译的C/C++文件路径。
第三步,编写C/C++代码。
在项目中创建一个jni目录,用于存放C/C++代码。
在该目录下,可以创建多个C/C++文件,用于实现不同的功能。
在编写代码时,需要注意使用C/C++的语法和规范,并且可以使用NDK提供的一些特定的API和函数。
第四步,编译C/C++代码。
在命令行中进入到项目的根目录下,执行命令"ndk-build",即可编译C/C++代码。
编译完成后,会生成对应的动态链接库文件(.so文件),可以在项目的libs目录下找到。
第五步,配置JNI接口。
在Java代码中,需要通过JNI(JavaNative Interface)来调用C/C++代码。
首先需要创建一个Java类,用于定义JNI接口。
在该类中,可以使用native关键字声明需要调用的C/C++函数。
然后,在命令行中执行命令"javah",可以生成对应的JNI头文件。
将该头文件拷贝到jni目录下,并在其中实现JNI函数的具体逻辑。
第六步,使用JNI接口。
在Java代码中,可以通过调用JNI接口来使用C/C++代码。
首先需要加载动态链接库文件,可以使用System.loadLibrary()方法来实现。
Eclipse下的Android-NDK安装
Android NDK环境简介Android NDK 是运行于Android 平台上的Native Development Kit 的缩写。
Android 应用开发者可以通过NDK 调用C 或C++ 本地代码。
NDK 编译需要用到Cygwin 中的make 和gcc, 所以先来下载并安装Cygwin。
NDK同时支持C和C++,但C++的支持相对要弱一些,比如,不支持异常,以及在调用静态构造函数和静态析构函数时,存在一些bug。
大多数情况下,使用NDK的目的,就是把和性能相关的代码,移到本地(native)层面去实现,你不大可能需要过多的OOP抽象以及其设计方面的优势(译者注:OOP往往会用到虚函数,而这会降低程序运行的性能。
设计模式更是如此,通常,设计模式在带来代码的可维护性和可扩展性优势的同时,几乎无可避免地带来性能方面的损害)。
我想说的就是,NDK的代码更倾向于用C编写,而不是C++。
NDK提供的API比较有限,这些API主要用于几个和性能相关的领域,比如:●OpenGL,包括支持(Java)SDK所支持的一些新版本●Math,(一些,但非全部的,专门针对计算的算法。
在native层面实现可获得更好的性能)●2D graphics,从2.2开始支持像素缓冲(pixelbuffer)●libc,提供了兼容性支持,并可能为移植现有native代码提供方便Step1:安装CDT在Eclipse中,进入Help – Install New Software菜单项,选择Galileo作为更新站点(“Work with”)。
等待更新项目树加载,然后选中Programming Languages分支下的Eclipse C/C++ Development Tools,然后点击Next按钮。
按照后续的提示,接受缺省的选项,最后必须接受许可,以便让Eclipse完成更新。
等待Eclipse重启。
现在你的Eclipse就支持C/C++了。
Android NDK 配置
Android NDK 配置Android NDK是什么, NDK:Native Develpment Kit.众所周知,Android是基于Linux的支持,自然对C、C++提供原生的支持,Android的开发也是基于Java的语言。
应用程序的运行环境主要是Dalvik虚拟机。
虽然开发语言是Java 但是我们总可以通过各种方式用C等语言开发。
至于用NDK开发的流程,请阅读NDK附带的文档。
关于具体的信息了解,请访问Android开发网阅读文档了解基本的信息。
点这里了解基本信息(需要设置代理访问或者翻墙)建议通读上面链接的全文(英文版),很多东西按照上面介绍的步骤就可以完全的成功。
一些基本的命令和操作也在里面可以看到,相信看过以后会对你有启发。
在其中有这么一句话:Please note that the NDK does not enable you to develop native-only applications. Android’s primary runtime remains the Dalvik virtual machine在NDK文档中也有这样的描述:The NDK is *not* a good way to write generic native code that runs on Android devices. In particular, your applications should still be written in the Java programming language, handle Android system events appropriately to avoid the "Application Not Responding" dialog or deal with the Android applicationlife-cycle.也就是说,Android的Application不能完全用C或者C++开发,其运行环境主要是Dalvik 的JVM,而且NDK没有关于组件声明周期和事件处理的东西。
Android NDK使用方法
Android NDK使用方法目前Android NDK只能编译出动态库.so文件,并不是能生成.apk文件,所以要调用底层的NDK程序必须分两个部分单独编写。
本文档将按照开发人员编码顺序介绍如何使用NDK。
本文使用的NDK版本为1.6r1版本,因为不想配置交叉编译环境直接使用了linux 版本的NDK在linux机器上编译。
1.首先让NDK环境正确配置完成然后才可以添加自己的代码编译。
下载Android 1.6r1NDK、解压到某一目录并将环境变量ANDROID_NDK_ROOT 设为你解压的NDK所在路径比如我现在的NDK放在/home/once下名字为android-ndk 那么就需要用这条命令来设置环境变量2.运行更新系统工具链依赖这点没什么好讲的如果第一步配置对了那么这一步NDK会根据你的配置生成对应的工具链3. 建立你自己的工作目录在apps目录下3.1比如我的工程会放在/home/once/android-ndk/apps/下面3.2然后拷贝一个例子工程里的Application.mk到你的目录并修改里面的参数为你的工程对应的值4.新建一个文件夹名为project 这个文件夹将用来存放你的jni工程以及java工程Java工程用eclipse辅助完成即可这里我们只讲JNI工程。
我们创立一个jni文件夹在project下然后同样从例子工程的jni文件夹下面拷贝一个Android.mk文件过来将里面的参数改对如下之所以会生成动态库是因为下面这句:如果你的工程还需要依赖其他的模块就需要指定如下参数:这个libtest其实就是我们上面的module名字所以上面的Application.mk得写好依赖关系否则这个库编译的时候会找不到test库还有就是如果你想在你的NDK的c代码中打印android log那么你得再依赖一个系统库:以上几个步骤全部做完了就可以进入第5点编译一下你的ndk库看看有没错误的了5.向上层目录进入到ndk的根目录,运行make APP=hello-jni(你的项目名称 V=1打印详细-B强制重编)比如我这里的工程为email 那么如果我要编译我的工程我就用这条命令 make APP=email 如果没有错误那么基本上说明你的c代码初步编译无误。
使用ndk-build编译生成.so文件
使用 ndk-build编译生成 .so文件
前言:以下都是基于懂得Android开发、jni的使用以及搭建好ndk开发环境的基础上。
在Android开发中经常会使用到jni,当安装了ndk环境后就拥有了编译c/c++文件的能力。 经常在eclipse里面可以配置一个builders后就能进行编译,但是如果闲麻烦的话也可以用ndk-build工具直接用命令编译。 1、添加ndk环境变量。 2、打开cmd->进入workspace->进入project->进入jni目录,键入ndk-build,就可以生成Android.mk配置里面对应的.so文件,这样就大功告成 了。 3、根据资料查阅,使用ndk-build太旧的版本不支持
local_prebuilt_jni_libs用法
local_prebuilt_jni_libs用法摘要:1.简介2.local_prebuilt_jni_libs 的作用3.使用方法4.注意事项5.总结正文:【1.简介】local_prebuilt_jni_libs 是Android 项目中一种用于集成JNI 库的方法。
通过使用local_prebuilt_jni_libs,开发者可以将JNI 库与项目的其他部分分离,从而简化构建过程并减少代码的耦合度。
【2.local_prebuilt_jni_libs 的作用】local_prebuilt_jni_libs 的主要作用是将JNI 库与Android 项目的其他部分解耦,使得开发者可以独立地更新和维护JNI 库。
这样可以简化项目的构建过程,避免因JNI 库更新导致整个项目重新构建。
同时,解耦后可以降低代码的耦合度,提高代码的可维护性。
【3.使用方法】使用local_prebuilt_jni_libs 的方法如下:1) 在项目的build.gradle 文件中,添加local_prebuilt_jni_libs 的依赖。
例如:```dependencies {// 其他依赖...prebuiltJniLibs "com.example:mylibrary:1.0.0"}```2) 在项目的根目录下,创建一个名为“jni”的文件夹。
将JNI 库文件(.so 文件)复制到该文件夹中。
3) 在项目的Android.mk 文件中,添加以下内容:```include $(CLEAR_VARS)LOCAL_MODULE := mylibraryLOCAL_SRC_FILES := jni/libmylibrary.soinclude $(PREBUILT_SHARED_LIBRARY)```这里,将JNI 库文件libmylibrary.so 添加到项目中,并设置模块名称为“mylibrary”。
NDK开发之cpu-features.h模块功能
NDK开发之cpu-features.h模块功能今天研究下cpufeatures库,它是⼀个轻量级的展⽰CPU特性的模块,调⽤者在运⾏时候可以根据这个库提供的简单接⼝获取到⽬标机的CPU架构和特性。
⼀、代码路径:$NDK_ROOT/sources/android/cpufeatures⼆、主要功能1. 获取⽬标机CPU架构,涵盖了android可能运⾏所有CPU架构,设置ABI的时候可以参考extern AndroidCpuFamily android_getCpuFamily(void);typedef enum {ANDROID_CPU_FAMILY_UNKNOWN = 0,ANDROID_CPU_FAMILY_ARM,ANDROID_CPU_FAMILY_X86,ANDROID_CPU_FAMILY_MIPS,ANDROID_CPU_FAMILY_ARM64,ANDROID_CPU_FAMILY_X86_64,ANDROID_CPU_FAMILY_MIPS64,ANDROID_CPU_FAMILY_MAX /* do not remove */} AndroidCpuFamily;2. 获取CPU性能,不同的CPU架构有不同的性能,例如arm⽀持的指令集有VFPV2、ARMv7-A、NEONextern uint64_t android_getCpuFeatures(void); // 注意:此⽅法32bit和64bit arm内核的返回不对等enum {ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0),ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1),ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2),ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3),ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4),ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5),ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6),ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7),ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8),ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9),ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10),ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11),ANDROID_CPU_ARM_FEATURE_AES = (1 << 12),ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13),ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14),ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15),ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16),};要⽀持不同的指令集,要添加对应的编译选项,详细见附录-mfpu=neon // ⽀持neon指令集3. 获取CPU个数extern int android_getCpuCount(void);4. 设置CPU个数,沙盒模拟测试extern int android_setCpu(int cpu_count, uint64_t cpu_features);extern uint32_t android_getCpuIdArm(void);extern int android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id);三、使⽤举例1. 以下展⽰了⼀个筛选armv7并⽀持neon指令集的代码#include <cpu-features.h>AndroidCUPFamily family = android_getCpuFamily();if (family != ANDROID_CPU_FAMILY_ARM){printf("Not an ARM CPU !\n");return;}uint64_t features = android_getCpuFeatures();if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7) == 0){printf("Not an ARMv7 CPU !\n")return;}if ((features & ANDROID_CPU_ARM_FEATURE_NEON) == 0){printf("CPU doesn't support NEON !\n");return;}2. ⼯程引⼊# build cpufeatures as a static libadd_library(cpufeatures STATIC ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) # include directoriestarget_include_directories(hello-neon PRIVATE ${ANDROID_NDK}/sources/android/cpufeatures) # linktarget_link_libraries(hello-neon cpufeatures)附录:/** Copyright (C) 2010 The Android Open Source Project* All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* * Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* * Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in* the documentation and/or other materials provided with the* distribution.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.*/#ifndef CPU_FEATURES_H#define CPU_FEATURES_H#include <sys/cdefs.h>#include <stdint.h>__BEGIN_DECLS/* A list of valid values returned by android_getCpuFamily().* They describe the CPU Architecture of the current process.*/typedef enum {ANDROID_CPU_FAMILY_UNKNOWN = 0,ANDROID_CPU_FAMILY_ARM,ANDROID_CPU_FAMILY_X86,ANDROID_CPU_FAMILY_MIPS,ANDROID_CPU_FAMILY_ARM64,ANDROID_CPU_FAMILY_X86_64,ANDROID_CPU_FAMILY_MIPS64,ANDROID_CPU_FAMILY_MAX /* do not remove */} AndroidCpuFamily;/* Return the CPU family of the current process.** Note that this matches the bitness of the current process. I.e. when* running a 32-bit binary on a 64-bit capable CPU, this will return the* 32-bit CPU family value.*/extern AndroidCpuFamily android_getCpuFamily(void);/* Return a bitmap describing a set of optional CPU features that are* supported by the current device's CPU. The exact bit-flags returned* depend on the value returned by android_getCpuFamily(). See the* documentation for the ANDROID_CPU_*_FEATURE_* flags below for details. */extern uint64_t android_getCpuFeatures(void);/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be* recognized by the library (see note below for 64-bit ARM). Value details* are:** VFPv2:* CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs * support these instructions. VFPv2 is a subset of VFPv3 so this will* be set whenever VFPv3 is set too.** ARMv7:* CPU supports the ARMv7-A basic instruction set.* This feature is mandated by the 'armeabi-v7a' ABI.** VFPv3:* CPU supports the VFPv3-D16 instruction set, providing hardware FPU* support for single and double precision floating point registers.* Note that only 16 FPU registers are available by default, unless* the D32 bit is set too. This feature is also mandated by the* 'armeabi-v7a' ABI.** VFP_D32:* CPU VFP optional extension that provides 32 FPU registers,* instead of 16. Note that ARM mandates this feature is the 'NEON'* feature is implemented by the CPU.** NEON:* CPU FPU supports "ARM Advanced SIMD" instructions, also known as* NEON. Note that this mandates the VFP_D32 feature as well, per the* ARM Architecture specification.** VFP_FP16:* Half-width floating precision VFP extension. If set, the CPU* supports instructions to perform floating-point operations on* 16-bit registers. This is part of the VFPv4 specification, but* not mandated by any Android ABI.** VFP_FMA:* Fused multiply-accumulate VFP instructions extension. Also part of* the VFPv4 specification, but not mandated by any Android ABI.** NEON_FMA:* Fused multiply-accumulate NEON instructions extension. Optional* extension from the VFPv4 specification, but not mandated by any* Android ABI.** IDIV_ARM:* Integer division available in ARM mode. Only available* on recent CPUs (e.g. Cortex-A15).** IDIV_THUMB2:* Integer division available in Thumb-2 mode. Only available* on recent CPUs (e.g. Cortex-A15).** iWMMXt:* Optional extension that adds MMX registers and operations to an* ARM CPU. This is only available on a few XScale-based CPU designs* sold by Marvell. Pretty rare in practice.** AES:* CPU supports AES instructions. These instructions are only* available for 32-bit applications running on ARMv8 CPU.** CRC32:* CPU supports CRC32 instructions. These instructions are only* available for 32-bit applications running on ARMv8 CPU.** SHA2:* CPU supports SHA2 instructions. These instructions are only* available for 32-bit applications running on ARMv8 CPU.** SHA1:* CPU supports SHA1 instructions. These instructions are only* available for 32-bit applications running on ARMv8 CPU.** PMULL:* CPU supports 64-bit PMULL and PMULL2 instructions. These* instructions are only available for 32-bit applications* running on ARMv8 CPU.** If you want to tell the compiler to generate code that targets one of* the feature set above, you should probably use one of the following* flags (for more details, see technical note at the end of this file):** -mfpu=vfp* -mfpu=vfpv2* These are equivalent and tell GCC to use VFPv2 instructions for* floating-point operations. Use this if you want your code to* run on *some* ARMv6 devices, and any ARMv7-A device supported* by Android.** Generated code requires VFPv2 feature.** -mfpu=vfpv3-d16* Tell GCC to use VFPv3 instructions (using only 16 FPU registers).* This should be generic code that runs on any CPU that supports the* 'armeabi-v7a' Android ABI. Note that no ARMv6 CPU supports this.** Generated code requires VFPv3 feature.** -mfpu=vfpv3* Tell GCC to use VFPv3 instructions with 32 FPU registers.* Generated code requires VFPv3|VFP_D32 features.** -mfpu=neon* Tell GCC to use VFPv3 instructions with 32 FPU registers, and* also support NEON intrinsics (see <arm_neon.h>).* Generated code requires VFPv3|VFP_D32|NEON features.** -mfpu=vfpv4-d16* Generated code requires VFPv3|VFP_FP16|VFP_FMA features.** -mfpu=vfpv4* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32 features.** -mfpu=neon-vfpv4* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|NEON|NEON_FMA * features.** -mcpu=cortex-a7* -mcpu=cortex-a15* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|* NEON|NEON_FMA|IDIV_ARM|IDIV_THUMB2* This flag implies -mfpu=neon-vfpv4.** -mcpu=iwmmxt* Allows the use of iWMMXt instrinsics with GCC.** IMPORTANT NOTE: These flags should only be tested when* android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a* 32-bit process.** When running a 64-bit ARM process on an ARMv8 CPU,* android_getCpuFeatures() will return a different set of bitflags*/enum {ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0),ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1),ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2),ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3),ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4),ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5),ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6),ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7),ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8),ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9),ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10),ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11),ANDROID_CPU_ARM_FEATURE_AES = (1 << 12),ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13),ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14),ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15),ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16),};/* The bit flags corresponding to the output of android_getCpuFeatures()* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details * are:** FP:* CPU has Floating-point unit.** ASIMD:* CPU has Advanced SIMD unit.** AES:* CPU supports AES instructions.** CRC32:* CPU supports CRC32 instructions.** SHA2:* CPU supports SHA2 instructions.** SHA1:* CPU supports SHA1 instructions.** PMULL:* CPU supports 64-bit PMULL and PMULL2 instructions.*/enum {ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0),ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1),ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2),ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3),ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4),ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5),ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6),};/* The bit flags corresponding to the output of android_getCpuFeatures()* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or* ANDROID_CPU_FAMILY_X86_64.*/enum {ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0),ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1),ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2),ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3),ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4),ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5),ANDROID_CPU_X86_FEATURE_AVX = (1 << 6),ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7),ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8),ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9),};/* The bit flags corresponding to the output of android_getCpuFeatures()* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS* or ANDROID_CPU_FAMILY_MIPS64. Values are:** R6:* CPU executes MIPS Release 6 instructions natively, and* supports obsoleted R1..R5 instructions only via kernel traps.** MSA:* CPU supports Mips SIMD Architecture instructions.*/enum {ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0),ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1),};/* Return the number of CPU cores detected on this device. */extern int android_getCpuCount(void);/* The following is used to force the CPU count and features* mask in sandboxed processes. Under 4.1 and higher, these processes* cannot access /proc, which is the only way to get information from* the kernel about the current hardware (at least on ARM).** It _must_ be called only once, and before any android_getCpuXXX* function, any other case will fail.** This function return 1 on success, and 0 on failure.*/extern int android_setCpu(int cpu_count,uint64_t cpu_features);#ifdef __arm__/* Retrieve the ARM 32-bit CPUID value from the kernel.* Note that this cannot work on sandboxed processes under 4.1 and * higher, unless you called android_setCpuArm() before.*/extern uint32_t android_getCpuIdArm(void);/* An ARM-specific variant of android_setCpu() that also allows you * to set the ARM CPUID field.*/extern int android_setCpuArm(int cpu_count,uint64_t cpu_features,uint32_t cpu_id);#endif__END_DECLS#endif /* CPU_FEATURES_H */。
ndk 编译
ndk 编译NDK是一种能够让开发者使用C/C++等语言编写Android应用程序的工具集。
NDK被广泛应用于需要高性能和底层硬件控制的应用,例如游戏、多媒体应用等。
NDK编译是将C/C++代码转换成Android应用程序的过程。
在NDK编译过程中,我们需要进行一系列配置和设置,方能使C/C++代码能在Android应用中正确运行。
本文将介绍NDK编译的流程、配置和注意事项。
一、NDK编译流程1、准备工作为了进行NDK编译,我们需要先下载NDK工具集以及安装好Android Studio。
然后,在Android Studio中安装好C++插件,以支持C/C++代码的开发。
2、创建项目在Android Studio中新建一个项目,然后选择“native C++”作为项目类型。
这样可以自动生成一些用于编写C/C++代码的文件和目录。
3、编写代码4、配置gradle文件我们需要在项目的gradle文件中指定编译选项和依赖项。
首先,在build.gradle中添加如下代码:此时,我们需要在CMakeLists.txt文件中指定编译选项和依赖项。
例如:```cppcmake_minimum_required(VERSION 3.4.1)target_link_libraries(native-lib# Android NDK librariesandroidlog)```5、进行编译最后,在Android Studio中点击“Sync Project with Gradle Files”按钮,然后再点击“Build”按钮,即可进行NDK编译。
下面是一些NDK编译的配置和注意事项。
1、指定C++标准和编译选项如果我们的C++代码中使用了某些C++11标准的特性,那么需要在gradle文件中指定C++标准。
例如:```cppexternalNativeBuild {cmake {cppFlags "-std=c++11"}}```我们也可以指定一些编译选项,例如“-O3”代表进行优化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android SDK开发教程目录1 环境配置 (3)1.1 编译过程 (3)1.2 Esclipse配置自动生成动态SO库 (3)1.3 Escplise配置生成头文件 (5)1.4 Escplise配置代码提示 (5)2 Android平台JNI开发实例 (6)2.1 Android平台的框架图 (6)2.2 HelloWorld程序实例 (7)2.3 头文件分析 (11)2.4方法的声明 (12)2.4.1方法基本组成 (12)2.4.2 JNIEnv * (12)2.4.3 方法前缀 (12)3 Android.mk解析 (13)3.1 Android.mk文件的用途 (13)3.2 自定义变量 (13)3.3 GNU Make系统变量 (14)3.4 模块描述变量 (14)3.5 NDK提供的函数宏 (15)3.6 Android.mk示例 (16)4 JNIEnv解析 (17)4.1 关于JNIEnv和JavaVM (17)4.2 注册和注销native函数 (20)4.3 在native中向LogCat输出调试信息 (21)4.4 关于jclass (22)4.5 native的char*和JAVA的String相互转换 (24)4.6 Java参数类型与本地参数类型对照 (25)5 Android NDK开发指南(一)Application.mk文件 (25)6 Android NDK开发指南(二)Android.mk文件 (27)6.1 概述 (27)6.2 实例分析 (27)7 Android Android.mk 规范 (29)7.1 系统变量解析 (29)7.2 NDK提供的宏功能及Anroid.mk 规范 (31)8 JNI 调用规范 (38)8.1 引言 (38)8.2 实现步骤及相关函数使用 (38)8.3 应用中注意事项 (43)9 JNI 之二:java & c/c++ 相互通信及调用 (44)10 C & C++ 中值得注意的编译,链接,调试,错误及其原因 (53)11 JAVA 中的内存泄漏 (58)11.1 Java Heap 的内存泄漏 (58)11.2 JVM 中native memory 的内存泄漏 (59)11.3 JNI编程中明显的内存泄漏 (59)11.3.1 Native Code 本身的内存泄漏 (59)11.3.2 Global Reference 引入的内存泄漏 (59)11.3.3 JNI 编程中潜在的内存泄漏——对LocalReference 的深入理解 (60)11.3.4 Local Reference 深层解析 (62)11.3.5 Local Reference 和Local Reference 表 (62)11.3.6 Local Reference 导致内存泄漏 (64)11.3.7 控制Local Reference 生命期 (65)11.4 常见问题 (65)11.4.1 jni调用java对象 (66)11.4.2 jni中引用的java对象的生命周期 (66)11.4.3 本地线程中调用java对象 (67)1 环境配置1.1 编译过程1)javah:javah -classpathbin\classes;D:\Android\adt-bundle-windows\sdk\platforms\android-18\android.jar–d jni com.coship.jni.MainActivity2)编写C/C++文件。
3)编写.mk文件LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jni --生成动态SO库名称LOCAL_SRC_FILES := hello-jni.c --C文件名称include $(BUILD_SHARED_LIBRARY)4)编译生成so库。
5)加载动态SO库static {System.loadLibrary("hello-jni");}1.2 Esclipse配置自动生成动态SO库1)增加NDK路径2)3)4)5)1.3 Escplise配置生成头文件1)路径:run—>2)配置命令:Location:${system_path:javah}Working Directory:${project_loc}\jniArguments:-classpath${project_loc}\bin\classes;E:\Android\adt-bundle-windows\sdk\platforms\android -19\android.jar -d ${project_loc}\jni ${java_type_name}3)运行:1.4 Escplise配置代码提示1)增加Nativie支持2)增加路径2 Android平台JNI开发实例2.1 Android平台的框架图首先看一下Android平台的框架图:可以看到Android上层的Application和ApplicationFramework都是使用Java编写,底层包括系统和使用众多的LIiraries都是C/C++编写的。
所以上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。
下面将学习Android是如何通过Jni来实现Java对C/C++函数的调用。
2.2 HelloWorld程序实例第一步:使用Java编写HelloWorld 的Android应用程序:package com.lucyfyr;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class HelloWorld extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.main);Log.v("dufresne", printJNI("I am HelloWorld Activity"));}static{//加载库文件System.loadLibrary("HelloWorldJni");}//声明原生函数参数为String类型返回类型为Stringprivate native String printJNI(String inputStr);}这一步我们可以使用eclipse来生成一个App;因为eclipse会自动为我们编译此Java文件,后面要是用到。
第二步:生成共享库的头文件:进入到eclipse生成的Android Project中:/HelloWorld/bin/classes/com/lucyfyr/ 下:可以看到里面后很多后缀为.class的文件,就是eclipse为我们自动编译好的java文件,其中就有:HelloWorld.class文件。
退回到classes一级目录:/HelloWorld/bin/classes/执行如下命令:javah com.lucyfyr.HelloWorld也可以指定到目录:Javah -classpath bin/classes;D:\Android\adt-bundle-windows\sdk\platforms\android-18\android.jar –d jni com.lucyfyr.HelloWorld生成文件:com_lucyfyr_HelloWorld.h/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_lucyfyr_HelloWorld */#ifndef _Included_com_lucyfyr_HelloWorld#define _Included_com_lucyfyr_HelloWorld#ifdef __cplusplusextern "C" {#endif/** Class: com_lucyfyr_HelloWorld* Method: printJNI* Signature: (Ljava/lang/String;)Ljava/lang/String;*/JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif可以看到自动生成对应的函数:Java_com_lucyfyr_HelloWorld_printJNIJava_ + 包名(com.lucyfyr) + 类名(HelloWorld) + 接口名(printJNI)必须要按此JNI规范来操作;java虚拟机就可以在com.simon.HelloWorld类调用printJNI接口的时候自动找到这个C实现的Native函数调用。
当然函数名太长,可以在.c文件中通过函数名映射表来实现简化。
第三步:实现JNI原生函数源文件:新建com_lucyfyr_HelloWorld.c文件:#include <jni.h>#define LOG_TAG "HelloWorld"#include <utils/Log.h>/* Native interface, it will be call in java code */JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr){LOGI("dufresne Hello World From libhelloworld.so!");// 从 instring 字符串取得指向字符串 UTF 编码的指针const char *str =(const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );LOGI("dufresne--->%s",(const char *)str);// 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。