Eclipse中实现Android+JNI编程需要解决以下几个问题:
1、Android的APK开发环境的搭建。
2、Native层C代码头文件的生成。
3、Native层Android.mk文件的编写。
4、Native层C代码的编译,获得.SO文件。
5、JAVA层到C层的调试。
一、Android的APK开发环境的搭建。
这个问题比较好解决,首先安装JDK,然后只需要从http://developer.android.com/sdk/index.html上下载ADT套件就可以了,该ADT包含Eclipse、SDK、CDT。
二、Native层C代码头文件的生成。
这个比较麻烦,现在Eclipse还没有提供自动生成Native层C代码头文件的功能,需要手动生成,例如有Android工程HelloJn,
就拿我这的环境来说,首先在终端下进入刚刚建立的HelloJni工程的目录:
ls查看工程文件braincol@ubuntu:~$ cd workspace/android/NDK/hello-jni/
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ls
AndroidManifest.xml assets bin default.properties gen res src
可以看到目前仅仅有几个标准的android应用程序的文件(夹)。
首先我们在工程目录下建立一个jni文件夹:
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ mkdir jni
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ls
AndroidManifest.xml assets bin default.properties gen jni res src
下面就可以生成相应的.h文件了:
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ javah -classpath bin -d jni com.example.hellojni.HelloJni
-classpath bin:表示类的路劲
-d jni: 表示生成的头文件存放的目录
com.example.hellojni.HelloJni 则是完整类名
这一步的成功要建立在已经在 bin/com/example/hellojni/ 目录下生成了 HelloJni.class的基础之上。
现在可以看到jni目录下多了个.h文件:
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ cd jni/
braincol@ubuntu:~/workspace/android/NDK/hello-jni/jni$ ls
com_example_hellojni_HelloJni.h
生成com_example_hellojni_HelloJni.h,可以将该文件改名为hello-jni.h。
三、Native层Android.mk文件的编写。
在jni目录下(即hello-jni.h同级目录下)新建一个Android.mk文件,Android.mk文件是Android 的 makefile文件
LOCAL_PATH := $(call my-dir)
一个Android.mk 文件首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
include $( CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),
除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。
LOCAL_MODULE := hello-jni
编译的目标对象,LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。
注意:编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'hello-jni'的共享库模块,将会生成'libhello-jni.so'文件。
重要注意事项:
如果你把库命名为‘libhello-jni’,编译系统将不会添加任何的lib前缀,也会生成 'libhello-jni.so',这是为了支持来源于Android平台的源代码的Android.mk文件,如果你确实需要这么做的话。
LOCAL_SRC_FILES := hello-jni.c
LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。
注意,默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始的小圆点(也就是’.cxx’,而不是’cxx’)
include $(BUILD_SHARED_LIBRARY)
四、Native层C代码的编译,获得.SO文件。BUILD_SHARED_LIBRARY表示编译生成共享库,是编译系统提供的变量,指向一个GNU Makefile脚本,负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。还有 BUILD_STATIC_LIBRARY变量表示生成静态库:lib$(LOCAL_MODULE).a, BUILD_EXECUTABLE 表示生成可执行文件。
如果要对C代码进行编译需要下载NDK包,配置NDK环境,通过配置NDK环境可以使用Eclipse进行.SO文件的自动生成,下载地址为:http://developer.android.com/tools/sdk/ndk/index.html#download。Eclipse和NDK配置步骤如下;
对于NDK的编译,切换到目标目录下,运行ndk-build脚本即可。
对于使用Eclipse开发,我们希望EC能自动的编译我们的NDK,那么只需要为工程添加一个Builders即可。
对于Windows的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK,所以为EC需要配置的builder,其实是执行Cygwin,然后传递ndk-build作为参数。在android-ndk-r8e开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。所以,windows和Linux上都可以类似的使用系统命令行直接进行NDK编译。
既然android-ndk-r8e来了,至于Cygwin的配置,就不说了。下面是使用android-ndk-r8e在windows下配置自动编译的builders的过程,对于Linux,只需要修改ndk-build.cmd为ndk-build即可了。
(1)测试准备:新建一个Eclipse工程,在工程目录下新建jni文件夹,其中写好必要的NDK编译的文件代码等。
(2)Project->Properties->Builders->New,新建一个Builder。
(3)在新建Builder中进行如下配置:
其中,Location为ndk-build.cmd的路径(PS:NDK的安装只需要解压到某一路径即可)。
Working Directory,为当前的工程下。这里的${}的表达是使用了EC的环境变量,可以使用Variables...按钮找到一些EC的环境变量。
对于Linux上的配置,和这里的配置一样,只是把Location的地址改为ndk-build即可。
(4)下面是Refresh选项卡和Build Options选项卡的配置:
其中,在配置Build Options的时候,点击Specify Resources按钮,选中工程下的jni文件夹如下:
这样,EC就能自动调用NDK脚本编译jni下的C/C++代码了。
五、JAVA层到C层的调试。
这部分是最蛋疼的部分,同时也是最重要的部分,但是根据我这几天尝试的经验来说,使用Eclipse无法实现可视化的调试,以下是Google官网的调试指导文档,步骤很简单,但是就是没成功过,最后我还是选择使用Eclipse和GDB进行联调,http://blog.csdn.net/u010681466/article/details/9097277。
ADT 20 includes an NDK plugin that provides support for building and debugging NDK projects in Eclipse. This document describes how to install and use the NDK plugin.
- Download Eclipse for Java.
- Install CDT from Eclipse update site http://download.eclipse.org/tools/cdt/releases/indigo.
- Install Android SDK + NDK Plugins from Eclipse update site https://dl-ssl.google.com/android/eclipse/
1. First set the path to SDK and NDK:
Eclipse -> Window -> Preferences -> Android -> set path to SDK
Eclipse -> Window -> Preferences -> Android -> NDK -> set path to the NDK
Note that you will not be able to add native support if the project already has C/C++ nature.
At this point, you will be able to build your applications using Project -> Build All.
Debugging native applications
1. Update your build config to include “NDK_DEBUG = 1”.
Right click project -> properties -> C/C++ Build:
3. Right click on your project, select Debug As -> Android Native Application
Note: There is a delay of a few seconds between when the activity is launched and when native debugging starts. If your code is already executed by that point, then you won’t see the breakpoint being hit. So either put a breakpoint in code that is called repetitively, or make sure that you call JNI code after you see that ndk-gdb has connected.