京鱼网www.jingfish.com


、开发环境搭建:
1.首先,要给 Eclipse 安装 CDT :
选择菜单 [Help] -> [Install new software...],
弹出 "Install" 窗口,
点击 Add 按钮,弹出 "Add Repository" 窗口,
在 Name: 文本框中输入 CDT ,
在 Location: 文本框中输入 http://download.eclipse.org/tools/cdt/releases/juno
点击 OK 按钮保存,

选择 Work with: 下列拉表框中的:
CDT - http://download.eclipse.org/tools/cdt/releases/juno

将 CDT Main Features 和 CDT Optional Features 两项全选中,
点击 Next> 按钮,按提示点击安装即可!

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

在安装了CDT插件后,要指定编译器。Project->Properties->C/C++Build ->Builder Settings->Build Command:在这里指定你的编译器的路径,我们这里用的是ndk-build,指定它所在的路径就好了。Build location:指定的是你的工程目录。



2.然后,要给 Eclipse 安装 Sequoyah :
选择菜单 [Help] -> [Install new software...],
弹出 "Install" 窗口,
点击 Add 按钮,弹出 "Add Repository" 窗口,
在 Name: 文本框中输入 Sequoyah ,
在 Location: 文本框中输入 http://download.eclipse.org/sequoyah/updates/2.0
注:在 http://www.eclipse.org/sequoyah/downloads/ 这里可以得到最新版的地址。
点击 OK 按钮保存,

选择 Work with: 下列拉表框中的:
sequoyah-2.0 - http://download.eclipse.org/sequoyah/updates/2.0

注意:一定要将 "Group items by category" 复选框的对勾去掉,
   不然会显示为 "There are no categorized items" !!!

将 [Sequoyah Android 本地化编辑器] 和 [Sequoyah Android 本机代码支持] 两项全选中,
点击 Next> 按钮,按提示点击安装即可!

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

3.最后,要设置本机开发 NDK 位置:
选择菜单 [Window] -> [Preferences],
弹出 "Preferences" 窗口,
在左侧窗栏中选择 Android -> 本机开发 选项,
在右侧窗栏中点击 Browse... 按钮,选择 NDK 解压后的目录,
点击右下角的 Apply 按钮保存设置。

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

4.把 NDK 目录下的 ndk-gdb 脚本的最后一句注释掉!
#$GDBCLIENT -x `native_path $GDBSETUP`

5.将 android-ndk-r8b 和 android-sdks/platform-tools 的全路径添加到 PATH 环境变量中:
$ sudo gedit /etc/environment
注:添加完之后用 $ . /etc/environment 重新加载一下新的 PATH 变量值。
  因为 ndk-build、ndk-gdb、adb 等脚本或工具要被调用时需要。

二、开发环境使用:
Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

1.新建或导入一个 Android 工程 TestJniPro,修改 java 代码,引用了一个本地库函数,例如:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_orange);
new AlertDialog.Builder( this ).setMessage( sayHello() ).show();
}

public native String sayHello(); // 本地库函数
static
{  
System.loadLibrary( "NativeCode" );  
}

2.在 工程名 上点击 右键 选择菜单 [Android Tools] -> [Add Native Support...],
弹出 "添加 Android 本机支持" 窗口,
确认一下 NDK 位置是否正确,
修改一下 将添加库名称 lib*.so 下的文本框中的库名(不含lib和.so)为你想要起的名字(如:NativeCode),
点击 finish 按钮后,
工程目录中应该多了一个 jni 目录,目录中有两个文件 库名.cpp 和 Android.mk 。
(例如:NativeCode.cpp)
Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

3.在 终端 里进入 jni 目录下,然后执行如下命令创建 jni 样式的头文件:
$ javah -classpath ../bin/classes wzh.nsc.TestJniProActivity
注:TestJniProActivity 类中定义引用了本地库函数,所以要用它来创建 jni 样式的头文件。

4.在 NativeCode.cpp 文件中添加代码:
#include "wzh_nsc_OrangeActivity.h"

JNIEXPORT jstring JNICALL
Java_wzh_nsc_orange_OrangeActivity_sayHello( JNIEnv* env,
jobject this )
{
return env->NewStringUTF( "Hello, I'm an Demo!" );
}

5.编译工程,如果出现如下错误:
Method 'NewStringUTF' could not be resolved 源代文件名.c /TestJNIC/jni line 6 Semantic Error  
Type 'JNIEnv' could not be resolved 源代文件名.c /TestJNIC/jni line 4 Semantic Error  
Type 'jobject' could not be resolved 源代文件名.c /TestJNIC/jni line 4 Semantic Error  
Type 'jstring' could not be resolved 源代文件名.c /TestJNIC/jni

解决办法:
右键点击 工程名 ,选择菜单 [Properties],
弹出 "Properties for 工程名" 窗口,
在窗口左窗栏中选择 C/C++ General -> Paths and Symbols ,
在窗口右窗栏中选择 Includes 选项页,
在 Language 栏中的
GNU C 和 GNU C++ 添加 绝对路径/android-ndk-r8b/platforms/android-8/arch-arm/usr/include


6.创建 Android 虚拟机,并运行它。


7.右键点击 工程名 ,选择菜单 [Run As] -> [1 Android Application],
来运行测试上面的程序是否可以正常运行。
注:如果在 Problems 选项页中出现类似如下错误:
make: *** No rule to make target `工程名_scd.mk'. Stop. 工程名 [Discovery Options] page in project properties C/C++ Problem

解决办法:
右键点击 工程名 ,选择菜单 [Properties],
弹出 "Properties for 工程名" 窗口,
在窗口左窗栏中选择 C/C++ Build ,
在窗口右窗栏中选择 Builder Settings 选项页,
去掉 Use default build command 复选框的对勾,
修改 Build command: 后面文本框中 ndk-build 为全路径!
在窗口右窗栏中选择 Behaviour 选项页,

修改 Build(Incremental build) 后面文本框将 V = 1 去掉,使之成为空文本框!




Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

注:如果此问题在联机调试依然存在,直接在它上面点击右键选删除即可!



Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

8.修改工程配置文件 AndroidManifest.xml ,将 Debuggable 标志设置为 true 。
Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

9.在 终端 中进入 工程目录 ,执行 ndk-gdb 命令,
将在 obj/local/armeabi 中生成了 app_process(可执行程序)、gdb.setup(配置文件) 等新文件。
注:执行这一步骤时,应当先确保程序是在模拟器中运行着。

右键点击 工程名 ,选择菜单 [Debug As] 或 主菜单 [Run] -> [Debug Configurations...],
弹出 "Debug Configurations" 窗口,
在窗口左窗栏中 双击 C/C++ Application ,其下才会出现 工程名 Default 选项,点击选择它,
在窗口右窗栏中选择 Main 选项页,
点击 Browse... 按钮,

修改 C/C++ Application: 下面的文本框内容为 工程目录下/obj/local/armeabi/app_process
注:这个文件是专为调试而存在的,假如发现找不到这个文件的话,就应当先在工程目录下运行一次 ndk-gdb 。

Project: 下面的文本框选择当前工程,一般不用修改,默认就是当前工程。

修改 Build(if required)before launching 组下的


Select configuration using 'C/C++ Application' 复选框打上勾;


Disable auto build 单选框被选中;


Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程
点击当前窗口正下方的 Using GDB(DSF) Create Process Launcher - Select other...
弹出 "Select Preferred Launcher" 窗口,
将 Use configuration specific settings Change Workspace Settings... 复选框勾选,
选中 Launchers: 列表框中的 Standard Create Process Launcher

Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

在窗口右窗栏中选择 Debugger 选项页,
修改 Debugger: 下拉列表框选项为 gdbserver
修改 Debugger Options 组下的 Main 选项页中的 GDB debugger: 后的文本框值为:
绝对目录/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb
注:这个路径下有很多文件针对其他平台的,别选错了。

修改 Debugger Options 组下的 Main 选项页中的 GDB command file: 后的文本框值为:
工程目录下/obj/local/armeabi/gdb2.setup
注:把 工程目录下/obj/local/armeabi/gdb.setup 复制一份,命名为 gdb2.setup ,
  把 gdb2.setup 最后一行的 target remote :5039 去掉。

  不设置指向 gdb.setup 的原因是:
  因为每次调用 ndk-gdb 的时候,都会产生一个新的 gdb.setup 来覆盖掉修改过的 gdb.setup 。

在 Debugger Options 组下的 Main 选项页中的
Verbose console mode 和 Use full file path to set breakpoints 两个复选框要勾上,
注:只有 Verbose console mode 记得勾上,才能在 Eclipse 控制台中用指令来与 gdb 交互。

在 Debugger Options 组下的 Connection 选项页中
修改 Type: 下拉列表框的值为 TCP
修改 Host name or IP address: 文本框的值为 localhost
修改 Port number: 文本框的值为 5039 
(注:因为 gdb.setup 的最后一行 target remote :5039 所以 Port number 设此值。)

点击当前窗口右下角的 Apply 按钮保存应用。

注:一定要点击 Debug 按钮,不然下图中的 TestJniPro_Default 就不会出现在菜单中!

10.现在就可以给代码设置断点了,一定要在调用 本地库函数 之前和之后各设置一个断点!
注:因为要给运行 ndk-gdb 留出时间。
开始正式的调试:
先运行项目的 java 调试,程序会运行到调用 本地库函数 之前的断点处停下来,
这个时候赶紧运行 终端 进入工程目录,然后运行 ndk-gdb ,运行之后是没有任何输出的,
然后启动 C/C++ 的 debug ,即上面配置好的那个:
右键点击 工程名 ,选择菜单 [Debug As] 或 主菜单 [Run] -> [Debug Configurations...],
弹出 "Debug Configurations" 窗口,
在窗口左窗栏中 双击 C/C++ Application ,其下才会出现 工程名 Default 选项,就是这个!
Ubuntu <wbr>下用 <wbr>Eclipse <wbr>编译调试 <wbr>Android <wbr>NDK <wbr>工程

Android 的模拟器是可以正常使用超级用户的权限的,
当你是用真机设备调试的时候请确保你的真机设备已经 root ,
否则会出现一些权限的错误,甚至导致莫名奇妙的问题...

对于 ndk-build 可编译成功并无任何错误、警告的代码,Eclipse 提示如下相关的错误:
"Symbol is not resolved"
"Member declaration not found"
"Invalid template argument"
"Invalid arguments"
"Method cannot be resolved"
等等

我的这个解决方案,可能并非完美解决方案,但是至少它将让你通过 Eclipse 点击 运行 或 调试 :
1.右键点击你的 Android 工程并选择属性;
2.在 C/C++ General 下点击 Code Analysis 项;
3.选择 Use project settings 单选项框;
4.将 Syntax and Semantic Errors 下的与 C++ 有关的实际能编译过去,但 Eclipse 报错误的,由 错误 改成 警告 。
ndk-build 编译时将会捕捉到每一个无论何种方式地真实的错误,所以不会有什么隐患,
对正确的 C++ 代码报错,可能是 Eclipse 的 bug !
(注:如果你知道更好的解决方案,请留言或发电子邮件告诉我啊,在此先谢过了 :))