Eclipse下NDK环境搭建实现Java、C\C++混合编程(图详)
Eclipse下NDK环境搭建实现Java、C\C++混合编程(图详)
一、Eclipse下NDK环境搭建
Windows7 64位旗舰版下,在搭建好Eclipse下Android开发环境前提下,Android开发环境搭建详情过程,请自行百度,一定注意Eclipse版本与ADT、SDK相互兼容。[转载请注明出处]
Android NDK系统框架图:

作者的NDK环境:
Jdk1.7版、Eclipse-jee-juno-win32最新版、ADT-23.0.4,SDK
请在Eclipse下Help——>Instrall NewSoftWare——> --All Available Sites-- 查找可用站点下载SDK
1)首先,下载安装ndk-r8,最新版本未必兼容Eclipse。
下载地址:http://developer.android.com/sdk/ndk/index.html
下载后解压缩待用。
2)链接ndk
在Eclipse下Window\Preferences——>Android——>NDK
在此要,选择刚刚解压缩的ndk文件根目录(提示:凡是安装目录命名一律英文,中文或数字开头的命名避免)
3)配置Builder(生成.os文件)
打开Eclipse,新建一个Android Application Project(取名为HelloNdk),在Project Explorer(工程目录)为HelloNdk新建jni文件夹,该文件夹就用来保存NDK需要编译的c/c++代码等。
项目根目录建立jni文件夹方法:
右击HelloNdk工程/Android Tools/Add Native Support…,.os文件默认命名为工程名HelloNdk,自带生成Android.mk和HelloNdk.cpp文件(有用)
(a)Project->Properties->Builders->New,新建一个Builder。
(b)在弹出的【Choose configuration type】对话框,选择【Program】,点击【OK】:
(c)在弹出的【Edit Configuration】对话框中,配置选项卡【Main】。
在“Name“中输入新builders的名称(我取名为Ndk_Builder)。
在“Location”中输入nkd-build.cmd的路径。
(我的是D:\AndroidDev\android-ndk-r7\ndk-build.cmd,根据各自的ndk路径设置,也可以点击“Browser File System…”来选取这个路径)。
在“Working Diretcoty”中输入${workspace_loc:/TestNdk}(也可以点击“Browse Workspace”来选取TestNdk目录)。

(d)【Edit Configuration】对话框中,配置选项卡【Refresh】。
勾选“Refresh resources upon completion”,
勾选“The entire workspace”,
勾选“Recuresively include sub-folders”。
(e)【Edit Configuration】对话框中,配置选项卡【Build options】。
勾选“After a “Clean””,
勾选“During manual builds”,
勾选“During auto builds”,
勾选“Specify working set of relevant resources”。
点击“Specify Resources…”

勾选TestNdk工程的“jni“目录,点击”finish“。
点击“OK“,完成配置。
4 配置C/C++ Build和C/C++ General
右击HelloNdk工程/Properties,打开Propeties for HelloNdk。
a) 左击C/C++ Build,如下图所示

b) 再设置C/C++ General——>Paths and Symbols,如下图所示

点击右边Add…,如下图所示

勾选如图,左击Variables按钮,弹出Select build variable对话框
提示:$(NDK_MORE) 为ndk_r8目录下 ...\android-ndk-r8\platforms\android-14\arch-arm\usr\include
作者已将其定义为系统变量NDK_MORE,设置方法同 jdk 环境变量 设置,见下图。

至此,Eclipse就能够自动调用NDK编译jin目录下的C/C++代码了。
二、 Demo运行
1) Scr\com.example.hellondk目录下新建JniClient.java
1 package com.example.hellondk; 2 3 public class JniClient { 4 public static native int AddInt(int a, int b); 5 }
2) 用cmd命令定位到JniClient.class 所在目录,输入“javac JniClient.java“后回车,作者项目目录截图如下:

3) 将在该目录下生产的JniClinet.class拷贝到HelloNdk\bin\classes\com\example\hellondk\目录内,其中有许多.class文件,(Eclipse会自动在该目录下生成JniClinet.class,最好还是覆盖)。
4) cmd命令定位到HelloNdk\bin\classes目录,输入”javah com.example.hellondk.JniClient“后回车。

5)在 HelloNdk\bin\classes目录内会【自动】生成com_example_hellondk_JniClient.h
将其拷贝到Eclipse的HelloNdk工程 \jni文件夹目录下。
com_example_hellondk_JniClient.h代码见下
1 /* DO NOT EDIT THIS FILE - it is machine generated */ 2 #include <jni.h> 3 /* Header for class com_example_hellondk_JniClient */ 4 5 #ifndef _Included_com_example_hellondk_JniClient 6 #define _Included_com_example_hellondk_JniClient 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 /* 11 * Class: com_example_hellondk_JniClient 12 * Method: AddInt 13 * Signature: (II)I 14 */ 15 JNIEXPORT jint JNICALL Java_com_example_hellondk_JniClient_AddInt 16 (JNIEnv *, jclass, jint, jint); 17 18 #ifdef __cplusplus 19 } 20 #endif 21 #endif
6) 将头文件中的AddInt函数声明复制到HelloNDK.cpp中,编写C++代码,实现两个数相加,返回结果和。
因为暂时没有编译,文件会有许多处错误,正常。
HelloNDK.cpp全部代码如下:
1 #include <jni.h> 2 #include <com_example_hellondk_JniClient.h> 3 JNIEXPORT jint JNICALL Java_com_niming_hellondk_JniClient_AddInt 4 (JNIEnv *env, jclass, jint a, jint b){ 5 return a + b; 6 }
7) 返回MainActivity.java我们来书写Java代码,调用刚刚编辑的C++函数。
利用一个Button,触发TextView显示两数和
12 public class MainActivity extends Activity { 13 14 final int a =10; 15 final int b = 8; 16 @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.activity_main); 20 21 final TextView tv = (TextView) findViewById(R.id.textView1); 22 Button btn = (Button) findViewById(R.id.button1); 23 btn.setOnClickListener(new OnClickListener(){ 24 25 @Override 26 public void onClick(View v) { 27 int c = JniClient.AddInt(a, b);//调用本地函数 28 final String str = Integer.toString(c); 29 tv.setText(str); 30 } 31 }); 32 33 } 34 static{ 35 System.loadLibrary("HelloNDK");//加载本地库 36 } 37 38 39 @Override 40 public boolean onCreateOptionsMenu(Menu menu) { 41 // Inflate the menu; this adds items to the action bar if it is present. 42 getMenuInflater().inflate(R.menu.main, menu); 43 return true; 44 } 45 46 }
activity_main.xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="95dp" android:layout_marginTop="61dp" android:text="TextView" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:text="加加" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button1" android:layout_marginTop="77dp" android:layout_toRightOf="@+id/textView1" android:text="Button" /> </RelativeLayout>
至此,代码全部书写完毕。
8) Eclipse中,Project / clean…

9) 我们发现C++代码被编译成.so文件(每次改动重复Project/clean…操作)

OK,第一个NDK_Demo完成,可以连接真机测试。
10) 右击项目HelloNdk\Run As…\Android Application查看结果

三、 小结
使用Java调用原生代码(C/C++)的大致过程:
1) 在Java类文件中加入新函数的声明,并将其定义为原生类型。见JniClient.java
2) 添加一个库的静态初始化器(initializer),原生函数将编译进这个库中。即System.loadLibrary("HelloNDK");
3) 向原生源文件中添加函数,头文件利用javah 命令自动生成如com_example_hellondk_JniClient.h,函数的命名需要遵循一定的命名规则,编写.cpp代码。
4) Project / clean…生成 .so文件
如 Install : libtemplateApp.so => libs/armeabi/libtemplateApp.so
5) Java调用、载入shared library(共享库)的.so文件,打包成 *.apk

浙公网安备 33010602011771号