2015年(24)
分类: Android平台
2015-09-06 22:25:37
没写过JNI的可以看看我之前的博客(Windows下利用Visual Studio开发的过程):http://cherishlc.iteye.com/admin/blogs/1328136
以及自动生成工具swig的使用方法(数组的支持不好!其他挺方便):http://cherishlc.iteye.com/admin/blogs/1689224
另外推荐一篇非常不错的NDK博文,(配置忽略,主要是各种数据的传递,下代码看看吧)http://vaero.blog.51cto.com/4350852/782787
扯远了,下面来看看真正在Android中的开发过程。
1、下载ADT及NDK
其中ADT中包含了Eclipse及google的开发套件,不用写C++的下载ADT就足够了。
NDK则是包含了GCC的编译器,以及各个平台(arm,X86,MIPS)的相关头文件,交叉编译的一些平台相关文件等。
2、在ADT中配置NDK路径
解压NDK压缩包到任意路径,按下图在ADT中(也即ADT解压后的Eclipse文件下的Eclipse中)设置NDK的路径。
设置方法如下图所示:
3、创建含有本地代码的Android Project
该过程分为以下两步:
具体过程如下图所示:
创建工程:
加入本地代码支持:
完成情况:
点击菜单栏Project->Build All命令进行编译。
注意:如果之前最小支持的API版本要不小于14,将出现编译错误。“Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 7 in ./AndroidManifest.xml”
解决方法如下:
打开AndroidManifest.xml,切换到源文件视图,将minSdkVersion 改为14以上:
4、编写Java端代码和C++端代码
Java端,注意不要继承自Android中的类,否则javah编译头文件时要指定android类路径。
javah推荐两种方法:
http://blog.csdn.net/stalendp/article/details/8712059
在Eclipse中配置javah外部工具方法为:
上图中最长的一行命令如下:
Cmdineclipse代码
-v
--------------------------------------------
${system_path:javah}
${project_loc}
-v -classpath "${project_loc}/bin/classes" -d "${project_loc}/jni" ${java_type_name}
选build all
[ Search Path: C:\Program Files\Java\jdk1.6.0_45\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\modules\jdk.boot.jar;C:\Program Files\Java\jdk1.6.0_45\jre\classes\C:\Users\1\workspace\TestNDK2/bin/classes ]
[Creating file C:\Users\1\workspace\TestNDK2/jni\com_lc_testndk2_NativeClass.h]
[源文件的搜索路径: C:\Users\1\workspace\TestNDK2\bin\classes]
[类文件的搜索路径: C:\Program Files\Java\jdk1.6.0_45\jre\lib\resources.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\modules\jdk.boot.jar,C:\Program Files\Java\jdk1.6.0_45\jre\classes,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunpkcs11.jar,C:\Users\1\workspace\TestNDK2\bin\classes]
[正在装入 C:\Users\1\workspace\TestNDK2\bin\classes\com\lc\testndk2\NativeClass.class]
[正在装入 java\lang\Object.class(java\lang:Object.class)]
[正在装入 java\lang\Throwable.class(java\lang:Throwable.class)]
[正在装入 java\lang\Class.class(java\lang:Class.class)]
[在718 毫秒内完成]
--------------------------------------------
配置好之后:
点刚才配置好的javah工具,生成.h文件,然后:
Java端调用JNI方法的代码:
将MainActivity改为:
编写C++代码:
打开刚才系统生成的TestNDK2.cpp,修改成如下样子:
5、配置生成的.so文件的目标平台
Java是跨平台的可是C++生成动态链接文件不是!!!同是Android,底层的CPU架构不同,动态链接文件也不同。。。好吧,这个我不知道原因。。。
于是乎,还得为不同的CPU创建不同的动态链接库文件,好在一行命令搞定~所有的动态链接一起打包,管他是哪个CPU,统统适用,Happy啊。
参考自: />
过程如下:
再编译时会发现生成了对应以上四个平台的.so文件~~~
一切搞定,可以运行了!!!运行结果如下:
6、Java与C++联合调试
参见:http://blog.csdn.net/wjr2012/article/details/7993722
注意:
过程为:
右键点击工程文件, 在properties -> C/C++ Build中:
---------------------------------------------------------------
http://blog.csdn.net/smfwuxiao/article/details/8523087
Android NDKr4引入了一个新的、小巧的shell脚本ndk-build,来简化源码编译。
该文件位于NDK根目录,进入你的工程根目录或子目录之后,在命令行下调用即可。例如:
NDK指向你的NDK的安装目录,PROJECT指向你的Android工程目录。建议将ndk-build所在目录加入PATH环境变量或设置alias。
所有给ndk-build的选项都会直接传给GNU Make,由make运行NDK的编译脚本。几个常见调用方式如下:
ndk-build
ndk-build clean
ndk-build NDK_DEBUG=1
ndk-build NDK_DEBUG=0
ndk-build V=1
ndk-build -B
ndk-build -B V=1
ndk-build NDK_LOG=1
ndk-build NDK_APP_APPLICATION_MK=<文件路径>
ndk-build -C <project路径>
在NDKr5中,ndk-build做了一些改进,使得在release和debug之间切换更容易了。即通过 NDK_DEBUG 变量:
ndk-build NDK_DEBUG=1
ndk-build NDK_DEBUG=0
如果没有指定NDK_DEBUG,则会从 AndroidManifest.xml中获取(查看 <application> 元素是否有 android:debuggable="true")。
注意:如果你的SDK是SDKr8或更高,完全不需要修改AndroidManifest.xml。因为如果你想编译出debug版安装包(在命令行下执行 ant debug或用ADT),SDK的工具会自动选择用NDK_DEBUG=1编译出的共享库。NDK编译出的debug版和release版的object文件存放在不同的目录(例如 obj/local/<abi>/objs 和 obj/local/<abi>/objs-debug),避免了在release和debug之间切换而重新编译所有文件。
总体来说,必须安装GNU Make 3.81 以上版本的make才能正常使用ndk-build和NDK。
ndk-build 其实就是对GNU Make的封装,它的目的是调用正确的NDK编译脚本,它等价于 make -f $NDK/build/core/build-local.mk [参数]
---------------------------------------------------------------
完了设置断点(只能在C++中)就可以启动调试了~~
好吧,,,调试怎么不灵光呢。。。再想想刚才的注意事项。。。好吧,早执行完了JNI代码了。。。
于是乎,修改MainActivity代码如下:
运行到断点的结果:
======================================================================================
注释部分:
随着支持Intel
随着Intel处理器的加入,相信越来越多基于x86的c/c++库将能更容易的被移植到android平台。
对于为x86进行android
1.
这点在NDK的手册中有说明,只需要在Application.mk中编辑APP_ABI
APP_ABI
这样就能生成支持android
说明:上面三种abi可以任意指定,也可以同时指定多个,默认为armeabi。
2.
要测试支持Intel处理器的android
The
从这里看到新版本的SDK工具应该是支持armv7和x86的模拟器的,然而打开SDK
尽管这里没有提供下载,但是AOSP中的android源码提供了编译android
关于如何编译android源码,可以参考:(说明:其内容没有完全更新,编译x86和arm的区别在于其中“choose
在编译源码后,我们可以得到下列文件:ramdisk.img,system.img,userdata.img(在out/target/product/generic_x86中),将上面的三个文件和源码prebuilt/android-x86/kernel中的kernel-qemu文件保存起来,如保存在一个新建的x86文件夹中。
下面就是如何在SDK中添加自己编译的x86模拟器,将上面的x86文件夹复制到:platforms\android-**\images中,同时将原有的文件移动到一个新的arm文件夹,这样,在使用AVD
说明:对于android-14和android-15,其中没有images文件夹,因为SDK将其移动到SDK根目录的system-images文件夹中了,可以自己新建此文件夹并在其中放置相关模拟器需要的文件即可。
说明:http://software.intel.com/en-us/articles/android-237-gingerbread-x86-emulator-image-add-on/提供了其它一些方法来使用android
总之,有多种方法可以对x86的android
3.
由于指令集等的不同,在用NDK移植某些程序的时候,可能需要考虑程序移植结果的正确性,就arm和x86对比而言,主要需要考虑的是:内存中字节对齐的差异、浮点数操作的差异、向量化指令的差异(NEON和SSE等)等。当然,并不是所有的程序都会在这些方面影响程序的结果。
在Intel官网上,有一些和android
那么,除了上面提到的一些问题,大家觉得x86和arm的NDK程序开发需要注意的问题还有哪些呢?欢迎大家一起讨论。
第6步我出现的问题是:
[2013-06-25 15:17:39 - TestNDK2] ------------------------------
[2013-06-25 15:17:39 - TestNDK2] Android Launch!
[2013-06-25 15:17:39 - TestNDK2] adb is running normally.
[2013-06-25 15:17:39 - TestNDK2] Performing com.lc.testndk2.MainActivity activity launch
[2013-06-25 15:17:39 - TestNDK2] Automatic Target Mode: launching new emulator with compatible AVD 'avd422'
[2013-06-25 15:17:39 - TestNDK2] Launching a new emulator with Virtual Device 'avd422'
[2013-06-25 15:17:39 - Emulator] emulator: warning: opening audio input failed
[2013-06-25 15:17:39 - Emulator]
[2013-06-25 15:17:39 - TestNDK2] New emulator found: emulator-5554
[2013-06-25 15:17:39 - TestNDK2] Waiting for HOME ('android.process.acore') to be launched...
[2013-06-25 15:18:06 - TestNDK2] HOME is up on device 'emulator-5554'
[2013-06-25 15:18:06 - TestNDK2] Uploading TestNDK2.apk onto device 'emulator-5554'
[2013-06-25 15:18:06 - TestNDK2] Installing TestNDK2.apk...
[2013-06-25 15:18:34 - TestNDK2] Success!
[2013-06-25 15:18:34 - TestNDK2] Starting activity com.lc.testndk2.MainActivity on device emulator-5554
[2013-06-25 15:18:36 - TestNDK2] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lc.testndk2/.MainActivity }
[2013-06-25 15:18:37 - TestNDK2] Attempting to connect debugger to 'com.lc.testndk2' on port 8631
[2013-06-25 15:25:22 - TestNDK2] gdbserver output:
[2013-06-25 15:25:22 - TestNDK2] run-as: exec failed for lib/gdbserver Error:No such file or directory
[2013-06-25 15:25:22 - TestNDK2] Verify if the application was built with NDK_DEBUG=1
gdb+gdbserver
----------------------------------------------
http://www.ibm.com/developerworks/cn/education/opensource/os-eclipse-tools/section2.html
设置新的 Ant 配置
第一个示例是 Ant 构建文件,该文件只创建一个包含一些经过编译的 Java 代码的 Java Archive (JAR),构建一个包含 Java 源代码的 JAR,并把两个 JAR 移到指定位置。
注:Ant 是一个构建工具 — 有点类似 Java 版本的 make
(极为简单的工具)— 该工具将使用 XML 格式的构建文件(默认情况下为 build.xml)。如果以前没使用过 Ant,您仍然能够继续学习本教程,但是可能需要以后花些时间了解 Ant 的更多信息(有关更多信息,请参阅侧栏 “了解 Ant 的更多信息”)。
虽然可以使用批处理 (.bat) 或 shell (.sh) 脚本创建 JAR 并把它们移到其他位置,但是有很多原因使我们必须使用 Ant 完成前述操作。一个原因是因为 Ant 构建是可移植的 — 如果计划要在其他操作系统中使用 Eclipse 中的配置,那么可移植性是必须要考虑的事项。由于 Eclipse 可以在 Windows、Mac 和 Linux 上运行,因此移植的可能性一定高于仅在一个操作系统中运行的 IDE。
使用 Ant 执行构建的第二个原因是 Ant 是一个常见工具 — 至少在 Java 社区中是这样的。Eclipse Europa 有一个适用于 Ant 构建文件的特殊编辑器,该编辑器内置了语法突出显示功能和模板,这样如果您刚开始接触 build.xml 文件,就可以获得来自 IDE 的一些额外帮助。并且由于 Ant 被广泛使用,因此,团队中的其他人员很可能理解 Ant build.xml 文件,而不理解 .bat 或 .sh 文件,当文件十分复杂时尤其如此。
清单 1 展示了样例 Ant 构建文件。您将在本教程中一直使用此构建文件来研究 Eclipse Europa 的功能。
<?xml version="1.0" encoding="UTF-8"?>
<project name="myAntExample" default="publish">
</project>
要在 Eclipse 中添加新的 Ant 启动配置,请选择
Main
您可以键入构建文件的名称,但是为了消除错误,我发现单击
浏览并选择构建文件后,请单击 ${workspace_loc:/exampleAntBuilder/build.xml}
。
通过只更新
在 <property>
传入自定义参数的一个原因是它允许您在不同项目中使用同一个构建文件,即使这些项目使用的目录和文件名不同。与使用同一 Ant 构建脚本的副本并针对各个项目进行相应调整相比,这可能是更好的替代方案。
Ant 将在 -D<property name>=<value>
dist.dir
变量(其中保存 JAR)的名称,则需要传入 -v -Ddist.dir=out
。这段代码将把目录名称设为
注:还可以从工具栏获得 Ant 构建配置。
除了提供静态数据字符串之外,您可以在 ${string_prompt}
-v -Ddist.dir=out -Dversion=${string_prompt}
。
插入完变量后,请单击
变量 | 说明 |
---|---|
build_files |
如果自动构建被启用,则此变量包括触发构建的文件的绝对路径。它支持使用参数缩小选择范围,例如,f |
build_project | 这是当前正在构建的项目的绝对路径。 |
build_type |
该变量表示正在执行的构建的类型(incremental、full、auto 或 none)。如果尝试在启动配置不是构建器的情况下使用此变量,则值为 |
container_loc | 这是当前资源的容器的绝对名称,可以是文件夹,也可以是目录。 |
container_name | 这是当前资源所在容器的名称。 |
container_path | 该变量表示容器到工作区的相对路径。 |
eclipse_home | 这是 Eclipse 的安装位置。 |
env_var | 该变量将输入给定环境变量的值,其中变量的名称可以作为实参提供给变量。 |
file_prompt | 当 Eclipse 启动程序时,它将显示一个文件选择器。在提示时将选择的文件名放入变量值中。 |
folder_prompt | 该变量与文件提示相同,但是只限于文件夹。 |
java_extensions_regex | 这是匹配正则表达式的已注册的类 Java 文件扩展名。 |
java_type_name | 该变量是所选资源中主要类型的完全限定的 Java 类型名。 |
project_loc | 这是项目在文件系统中的绝对路径。 |
project_name | 这是项目的名称。 |
project_path | 这是当前项目到工作区的相对路径。 |
resource_loc | 该变量表示当前资源在文件系统中的绝对路径。 |
resource_name | 这是资源的名称。 |
resource_path | 这是当前资源到工作区的相对路径。 |
selected_text | 这是选中的文本的值(如果有的话)。 |
string_prompt | 如果使用该变量,Eclipse 将提示您输入字符串值。您在提示时输入的任何内容都将被替换到变量中。 |
system | 这是 Eclipse 系统变量值(ARCH、ECLIPSE_HOME、NL、OS、WS)。 |
system_path | 该变量是作为实参提供的工具在文件系统中的绝对路径。 |
system_property | 这是来自 Eclipse 运行时的系统属性值,其中属性名是变量的实参。 |
target.arch | 该变量表示目标处理器架构(例如,适用于 Intel? 处理器的 x86)。 |
target.nl | 这是目标语言环境(例如,en_US 或 fr_FR)。 |
target.os | 这是目标操作系统(例如,macosx)。 |
target.ws | 该变量表示目标窗口系统(例如,Mac 的 Carbon)。 |
target_home | 这是目标主目录,它与 Eclipse 主目录相同。 |
workspace_loc | 这是工作区在文件系统中的绝对路径。 |
连同属性的覆盖值一起传入 Ant 配置的其他有用实参是允许调整日志记录的那些实参。例如,-logfile <filename>
-q
、-v
-d
=================================================================================
http://blog.sina.com.cn/s/blog_697bbefe0100vqzc.html
eclipse调试android
在经历了无数纠结后,决定写下这篇文章,让后面的开发人员少走弯路~
博文中的图片来自原文,可能会与我的开发环境有少许不同,但是整体步骤是对的。本人在以下环境中测试通过:
系统:Ubuntu 11.04
NDK版本:r6
eclipse版本:3.7
参考原文:
http://www.eclipse.org/sequoyah/documentation/native_debug.php
首先下面5步设置eclipse
第1步:
在AndroidManifest.xml文件中application项中加入android:debuggable="true",你也可以在eclipse里的可视化中设置,如下图。
第2步:设置你的C/C++调试选项
在Main的选项卡中,在C/C++ Application里面选择app_process作为调试对象(app_process文件会在你运行ndk-gdb时候生成)!而不是你编译出来的*.so文件!这个文件会在 你的项目路径/obj/local/armeabi/app_process
还有记得选择Disable auto build 配置如下图
接下来点击图片中红色方框特别标志的地方,设置启动调试的进一步参数
第3步:选择调试启动方式
选择Standard Create Process 然后确定,如图
第4步:
在Debugger的选项卡中设置debugger模式为gdbserver,而Stop on start at就填你希望当调试开始时候的断点函数名(注意:这个函数名是C/C++的函数名称,即使你没有打上断点当运行到这个函数时会自动暂停)
在Debugger Option栏目框里的Main选项卡的GDB Debugger选择NDK的gdb,这个文件在
第5步:
在Debugger Option栏目框里的Connection选项卡设置连接类型Type为TCP,端口Port number为5039,如图
最后修改ndk-gdb这个文件,该文件位于你的NDK目录下,先将该文件做个拷贝,命名为ndk-gdb2,然后打开,将最后一行
具体调试步骤:
1.用eclipse启动android的java调试在你自己的Activity类中的onCreate方法中加一个断点,避免程序一闪而过你还没来得及启动C/C++部分的调试。
2.在你的工程目录下运行刚才修改好的ndk-gdb2,如果你需要一些信息可以在后面加上--verbose参数。
3.启动eclipse的C/C++调试
启动成功后如下图(这张图是我自己的,呵呵...)
一些比较弱智的个人心得:
android的模拟器是可以正常使用超级用户的权限的,当你是用真机设备调试的时候请确保你的真机设备已经root否则会出现一些权限的错误,甚至导致莫名奇妙的问题...我就被这些问题纠结了几天....
标签:
it |
http://cherishlc.iteye.com/blog/1756762
在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux)。
没写过JNI的可以看看我之前的博客(Windows下利用Visual Studio开发的过程):http://cherishlc.iteye.com/admin/blogs/1328136
以及自动生成工具swig的使用方法(数组的支持不好!其他挺方便):http://cherishlc.iteye.com/admin/blogs/1689224
另外推荐一篇非常不错的NDK博文,(配置忽略,主要是各种数据的传递,下代码看看吧)http://vaero.blog.51cto.com/4350852/782787
扯远了,下面来看看真正在Android中的开发过程。
1、下载ADT及NDK
其中ADT中包含了Eclipse及google的开发套件,不用写C++的下载ADT就足够了。
NDK则是包含了GCC的编译器,以及各个平台(arm,X86,MIPS)的相关头文件,交叉编译的一些平台相关文件等。
2、在ADT中配置NDK路径
解压NDK压缩包到任意路径,按下图在ADT中(也即ADT解压后的Eclipse文件下的Eclipse中)设置NDK的路径。
设置方法如下图所示:
3、创建含有本地代码的Android Project
该过程分为以下两步:
具体过程如下图所示:
创建工程:
加入本地代码支持:
完成情况:
点击菜单栏Project->Build All命令进行编译。
注意:如果之前最小支持的API版本要不小于14,将出现编译错误。“Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 7 in ./AndroidManifest.xml”
解决方法如下:
打开AndroidManifest.xml,切换到源文件视图,将minSdkVersion 改为14以上:
4、编写Java端代码和C++端代码
Java端,注意不要继承自Android中的类,否则javah编译头文件时要指定android类路径。
javah推荐两种方法:
http://blog.csdn.net/stalendp/article/details/8712059
在Eclipse中配置javah外部工具方法为:
上图中最长的一行命令如下:
Cmdineclipse代码
-v
--------------------------------------------
${system_path:javah}
${project_loc}
-v -classpath "${project_loc}/bin/classes" -d "${project_loc}/jni" ${java_type_name}
选build all
[ Search Path: C:\Program Files\Java\jdk1.6.0_45\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_45\jre\lib\modules\jdk.boot.jar;C:\Program Files\Java\jdk1.6.0_45\jre\classes\C:\Users\1\workspace\TestNDK2/bin/classes ]
[Creating file C:\Users\1\workspace\TestNDK2/jni\com_lc_testndk2_NativeClass.h]
[源文件的搜索路径: C:\Users\1\workspace\TestNDK2\bin\classes]
[类文件的搜索路径: C:\Program Files\Java\jdk1.6.0_45\jre\lib\resources.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\modules\jdk.boot.jar,C:\Program Files\Java\jdk1.6.0_45\jre\classes,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext\sunpkcs11.jar,C:\Users\1\workspace\TestNDK2\bin\classes]
[正在装入 C:\Users\1\workspace\TestNDK2\bin\classes\com\lc\testndk2\NativeClass.class]
[正在装入 java\lang\Object.class(java\lang:Object.class)]
[正在装入 java\lang\Throwable.class(java\lang:Throwable.class)]
[正在装入 java\lang\Class.class(java\lang:Class.class)]
[在718 毫秒内完成]
--------------------------------------------
配置好之后:
点刚才配置好的javah工具,生成.h文件,然后:
Java端调用JNI方法的代码:
将MainActivity改为:
编写C++代码:
打开刚才系统生成的TestNDK2.cpp,修改成如下样子:
5、配置生成的.so文件的目标平台
Java是跨平台的可是C++生成动态链接文件不是!!!同是Android,底层的CPU架构不同,动态链接文件也不同。。。好吧,这个我不知道原因。。。
于是乎,还得为不同的CPU创建不同的动态链接库文件,好在一行命令搞定~所有的动态链接一起打包,管他是哪个CPU,统统适用,Happy啊。
参考自: />
过程如下:
再编译时会发现生成了对应以上四个平台的.so文件~~~
一切搞定,可以运行了!!!运行结果如下:
6、Java与C++联合调试
参见:http://blog.csdn.net/wjr2012/article/details/7993722
注意:
过程为:
右键点击工程文件, 在properties -> C/C++ Build中:
---------------------------------------------------------------
http://blog.csdn.net/smfwuxiao/article/details/8523087
Android NDKr4引入了一个新的、小巧的shell脚本ndk-build,来简化源码编译。
该文件位于NDK根目录,进入你的工程根目录或子目录之后,在命令行下调用即可。例如:
NDK指向你的NDK的安装目录,PROJECT指向你的Android工程目录。建议将ndk-build所在目录加入PATH环境变量或设置alias。
所有给ndk-build的选项都会直接传给GNU Make,由make运行NDK的编译脚本。几个常见调用方式如下:
ndk-build
ndk-build clean
ndk-build NDK_DEBUG=1
ndk-build NDK_DEBUG=0
ndk-build V=1
ndk-build -B
ndk-build -B V=1
ndk-build NDK_LOG=1
ndk-build NDK_APP_APPLICATION_MK=<文件路径>
ndk-build -C <project路径>
在NDKr5中,ndk-build做了一些改进,使得在release和debug之间切换更容易了。即通过 NDK_DEBUG 变量:
ndk-build NDK_DEBUG=1
ndk-build NDK_DEBUG=0
如果没有指定NDK_DEBUG,则会从 AndroidManifest.xml中获取(查看 <application> 元素是否有 android:debuggable="true")。
注意:如果你的SDK是SDKr8或更高,完全不需要修改AndroidManifest.xml。因为如果你想编译出debug版安装包(在命令行下执行 ant debug或用ADT),SDK的工具会自动选择用NDK_DEBUG=1编译出的共享库。NDK编译出的debug版和release版的object文件存放在不同的目录(例如 obj/local/<abi>/objs 和 obj/local/<abi>/objs-debug),避免了在release和debug之间切换而重新编译所有文件。
总体来说,必须安装GNU Make 3.81 以上版本的make才能正常使用ndk-build和NDK。
ndk-build 其实就是对GNU Make的封装,它的目的是调用正确的NDK编译脚本,它等价于 make -f $NDK/build/core/build-local.mk [参数]
---------------------------------------------------------------
完了设置断点(只能在C++中)就可以启动调试了~~
好吧,,,调试怎么不灵光呢。。。再想想刚才的注意事项。。。好吧,早执行完了JNI代码了。。。
于是乎,修改MainActivity代码如下:
运行到断点的结果:
======================================================================================
注释部分:
随着支持Intel
随着Intel处理器的加入,相信越来越多基于x86的c/c++库将能更容易的被移植到android平台。
对于为x86进行android
1.
这点在NDK的手册中有说明,只需要在Application.mk中编辑APP_ABI
APP_ABI
这样就能生成支持android
说明:上面三种abi可以任意指定,也可以同时指定多个,默认为armeabi。
2.
要测试支持Intel处理器的android
The
从这里看到新版本的SDK工具应该是支持armv7和x86的模拟器的,然而打开SDK
尽管这里没有提供下载,但是AOSP中的android源码提供了编译android
关于如何编译android源码,可以参考:(说明:其内容没有完全更新,编译x86和arm的区别在于其中“choose
在编译源码后,我们可以得到下列文件:ramdisk.img,system.img,userdata.img(在out/target/product/generic_x86中),将上面的三个文件和源码prebuilt/android-x86/kernel中的kernel-qemu文件保存起来,如保存在一个新建的x86文件夹中。
下面就是如何在SDK中添加自己编译的x86模拟器,将上面的x86文件夹复制到:platforms\android-**\images中,同时将原有的文件移动到一个新的arm文件夹,这样,在使用AVD
说明:对于android-14和android-15,其中没有images文件夹,因为SDK将其移动到SDK根目录的system-images文件夹中了,可以自己新建此文件夹并在其中放置相关模拟器需要的文件即可。
说明:http://software.intel.com/en-us/articles/android-237-gingerbread-x86-emulator-image-add-on/提供了其它一些方法来使用android
总之,有多种方法可以对x86的android
3.
由于指令集等的不同,在用NDK移植某些程序的时候,可能需要考虑程序移植结果的正确性,就arm和x86对比而言,主要需要考虑的是:内存中字节对齐的差异、浮点数操作的差异、向量化指令的差异(NEON和SSE等)等。当然,并不是所有的程序都会在这些方面影响程序的结果。
在Intel官网上,有一些和android
那么,除了上面提到的一些问题,大家觉得x86和arm的NDK程序开发需要注意的问题还有哪些呢?欢迎大家一起讨论。
第6步我出现的问题是:
[2013-06-25 15:17:39 - TestNDK2] ------------------------------
[2013-06-25 15:17:39 - TestNDK2] Android Launch!
[2013-06-25 15:17:39 - TestNDK2] adb is running normally.
[2013-06-25 15:17:39 - TestNDK2] Performing com.lc.testndk2.MainActivity activity launch
[2013-06-25 15:17:39 - TestNDK2] Automatic Target Mode: launching new emulator with compatible AVD 'avd422'
[2013-06-25 15:17:39 - TestNDK2] Launching a new emulator with Virtual Device 'avd422'
[2013-06-25 15:17:39 - Emulator] emulator: warning: opening audio input failed
[2013-06-25 15:17:39 - Emulator]
[2013-06-25 15:17:39 - TestNDK2] New emulator found: emulator-5554
[2013-06-25 15:17:39 - TestNDK2] Waiting for HOME ('android.process.acore') to be launched...
[2013-06-25 15:18:06 - TestNDK2] HOME is up on device 'emulator-5554'
[2013-06-25 15:18:06 - TestNDK2] Uploading TestNDK2.apk onto device 'emulator-5554'
[2013-06-25 15:18:06 - TestNDK2] Installing TestNDK2.apk...
[2013-06-25 15:18:34 - TestNDK2] Success!
[2013-06-25 15:18:34 - TestNDK2] Starting activity com.lc.testndk2.MainActivity on device emulator-5554
[2013-06-25 15:18:36 - TestNDK2] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lc.testndk2/.MainActivity }
[2013-06-25 15:18:37 - TestNDK2] Attempting to connect debugger to 'com.lc.testndk2' on port 8631
[2013-06-25 15:25:22 - TestNDK2] gdbserver output:
[2013-06-25 15:25:22 - TestNDK2] run-as: exec failed for lib/gdbserver Error:No such file or directory
[2013-06-25 15:25:22 - TestNDK2] Verify if the application was built with NDK_DEBUG=1
gdb+gdbserver
----------------------------------------------
http://www.ibm.com/developerworks/cn/education/opensource/os-eclipse-tools/section2.html
设置新的 Ant 配置
第一个示例是 Ant 构建文件,该文件只创建一个包含一些经过编译的 Java 代码的 Java Archive (JAR),构建一个包含 Java 源代码的 JAR,并把两个 JAR 移到指定位置。
注:Ant 是一个构建工具 — 有点类似 Java 版本的 make
(极为简单的工具)— 该工具将使用 XML 格式的构建文件(默认情况下为 build.xml)。如果以前没使用过 Ant,您仍然能够继续学习本教程,但是可能需要以后花些时间了解 Ant 的更多信息(有关更多信息,请参阅侧栏 “了解 Ant 的更多信息”)。
虽然可以使用批处理 (.bat) 或 shell (.sh) 脚本创建 JAR 并把它们移到其他位置,但是有很多原因使我们必须使用 Ant 完成前述操作。一个原因是因为 Ant 构建是可移植的 — 如果计划要在其他操作系统中使用 Eclipse 中的配置,那么可移植性是必须要考虑的事项。由于 Eclipse 可以在 Windows、Mac 和 Linux 上运行,因此移植的可能性一定高于仅在一个操作系统中运行的 IDE。
使用 Ant 执行构建的第二个原因是 Ant 是一个常见工具 — 至少在 Java 社区中是这样的。Eclipse Europa 有一个适用于 Ant 构建文件的特殊编辑器,该编辑器内置了语法突出显示功能和模板,这样如果您刚开始接触 build.xml 文件,就可以获得来自 IDE 的一些额外帮助。并且由于 Ant 被广泛使用,因此,团队中的其他人员很可能理解 Ant build.xml 文件,而不理解 .bat 或 .sh 文件,当文件十分复杂时尤其如此。
清单 1 展示了样例 Ant 构建文件。您将在本教程中一直使用此构建文件来研究 Eclipse Europa 的功能。
<?xml version="1.0" encoding="UTF-8"?>
<project name="myAntExample" default="publish">
</project>
要在 Eclipse 中添加新的 Ant 启动配置,请选择
Main
您可以键入构建文件的名称,但是为了消除错误,我发现单击
浏览并选择构建文件后,请单击 ${workspace_loc:/exampleAntBuilder/build.xml}
。
通过只更新
在 <property>
传入自定义参数的一个原因是它允许您在不同项目中使用同一个构建文件,即使这些项目使用的目录和文件名不同。与使用同一 Ant 构建脚本的副本并针对各个项目进行相应调整相比,这可能是更好的替代方案。
Ant 将在 -D<property name>=<value>
dist.dir
变量(其中保存 JAR)的名称,则需要传入 -v -Ddist.dir=out
。这段代码将把目录名称设为
注:还可以从工具栏获得 Ant 构建配置。
除了提供静态数据字符串之外,您可以在 ${string_prompt}
-v -Ddist.dir=out -Dversion=${string_prompt}
。
插入完变量后,请单击
变量 | 说明 |
---|---|
build_files |
如果自动构建被启用,则此变量包括触发构建的文件的绝对路径。它支持使用参数缩小选择范围,例如,f |
build_project | 这是当前正在构建的项目的绝对路径。 |
build_type |
该变量表示正在执行的构建的类型(incremental、full、auto 或 none)。如果尝试在启动配置不是构建器的情况下使用此变量,则值为 |
container_loc | 这是当前资源的容器的绝对名称,可以是文件夹,也可以是目录。 |
container_name | 这是当前资源所在容器的名称。 |
container_path | 该变量表示容器到工作区的相对路径。 |
eclipse_home | 这是 Eclipse 的安装位置。 |
env_var | 该变量将输入给定环境变量的值,其中变量的名称可以作为实参提供给变量。 |
file_prompt | 当 Eclipse 启动程序时,它将显示一个文件选择器。在提示时将选择的文件名放入变量值中。 |
folder_prompt | 该变量与文件提示相同,但是只限于文件夹。 |
java_extensions_regex | 这是匹配正则表达式的已注册的类 Java 文件扩展名。 |
java_type_name | 该变量是所选资源中主要类型的完全限定的 Java 类型名。 |
project_loc | 这是项目在文件系统中的绝对路径。 |
project_name | 这是项目的名称。 |
project_path | 这是当前项目到工作区的相对路径。 |
resource_loc | 该变量表示当前资源在文件系统中的绝对路径。 |
resource_name | 这是资源的名称。 |
resource_path | 这是当前资源到工作区的相对路径。 |
selected_text | 这是选中的文本的值(如果有的话)。 |
string_prompt | 如果使用该变量,Eclipse 将提示您输入字符串值。您在提示时输入的任何内容都将被替换到变量中。 |
system | 这是 Eclipse 系统变量值(ARCH、ECLIPSE_HOME、NL、OS、WS)。 |
system_path | 该变量是作为实参提供的工具在文件系统中的绝对路径。 |
system_property | 这是来自 Eclipse 运行时的系统属性值,其中属性名是变量的实参。 |
target.arch | 该变量表示目标处理器架构(例如,适用于 Intel? 处理器的 x86)。 |
target.nl | 这是目标语言环境(例如,en_US 或 fr_FR)。 |
target.os | 这是目标操作系统(例如,macosx)。 |
target.ws | 该变量表示目标窗口系统(例如,Mac 的 Carbon)。 |
target_home | 这是目标主目录,它与 Eclipse 主目录相同。 |
workspace_loc | 这是工作区在文件系统中的绝对路径。 |
连同属性的覆盖值一起传入 Ant 配置的其他有用实参是允许调整日志记录的那些实参。例如,-logfile <filename>
-q
、-v
-d
=================================================================================
http://blog.sina.com.cn/s/blog_697bbefe0100vqzc.html
eclipse调试android
在经历了无数纠结后,决定写下这篇文章,让后面的开发人员少走弯路~
博文中的图片来自原文,可能会与我的开发环境有少许不同,但是整体步骤是对的。本人在以下环境中测试通过:
系统:Ubuntu 11.04
NDK版本:r6
eclipse版本:3.7
参考原文:
http://www.eclipse.org/sequoyah/documentation/native_debug.php
首先下面5步设置eclipse
第1步:
在AndroidManifest.xml文件中application项中加入android:debuggable="true",你也可以在eclipse里的可视化中设置,如下图。
第2步:设置你的C/C++调试选项
在Main的选项卡中,在C/C++ Application里面选择app_process作为调试对象(app_process文件会在你运行ndk-gdb时候生成)!而不是你编译出来的*.so文件!这个文件会在 你的项目路径/obj/local/armeabi/app_process
还有记得选择Disable auto build 配置如下图
接下来点击图片中红色方框特别标志的地方,设置启动调试的进一步参数
第3步:选择调试启动方式
选择Standard Create Process 然后确定,如图
第4步:
在Debugger的选项卡中设置debugger模式为gdbserver,而Stop on start at就填你希望当调试开始时候的断点函数名(注意:这个函数名是C/C++的函数名称,即使你没有打上断点当运行到这个函数时会自动暂停)
在Debugger Option栏目框里的Main选项卡的GDB Debugger选择NDK的gdb,这个文件在
第5步:
在Debugger Option栏目框里的Connection选项卡设置连接类型Type为TCP,端口Port number为5039,如图
最后修改ndk-gdb这个文件,该文件位于你的NDK目录下,先将该文件做个拷贝,命名为ndk-gdb2,然后打开,将最后一行
具体调试步骤:
1.用eclipse启动android的java调试在你自己的Activity类中的onCreate方法中加一个断点,避免程序一闪而过你还没来得及启动C/C++部分的调试。
2.在你的工程目录下运行刚才修改好的ndk-gdb2,如果你需要一些信息可以在后面加上--verbose参数。
3.启动eclipse的C/C++调试
启动成功后如下图(这张图是我自己的,呵呵...)
一些比较弱智的个人心得:
android的模拟器是可以正常使用超级用户的权限的,当你是用真机设备调试的时候请确保你的真机设备已经root否则会出现一些权限的错误,甚至导致莫名奇妙的问题...我就被这些问题纠结了几天.