赞
踩
在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该过程分为以下两步:
创建普通的Android Application工程(注意最小支持的API版本要不小于14)
加入本地代码支持
具体过程如下图所示:
创建工程:
加入本地代码支持:
完成情况:
点击菜单栏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类路径。
packagecom.lc.testndk2;
importandroid.util.Log;
publicclassNativeClass {
//数组a中的每个元素都加上b,返回值为在C++中数据是否为a中数据拷贝得到的(按值拷贝还是传递指针)
publicstaticnativebooleanjniArrayAdd(int[] a,intb);
// 在C++中创建Java中的int数组,其中元素为 数组a中的对应元素乘以b
publicstaticnativeint[] jnitArrayMul(int[] a,intb);
static{
Log.i("NativeClass","before load library");
System.loadLibrary("TestNDK2");//注意这里为自己指定的.so文件,无lib前缀,亦无后缀
Log.i("NativeClass","after load library");
}
}
javah推荐两种方法:
在Eclipse中配置javah外部工具方法为:
上图中最长的一行命令如下:
Cmdineclipse代码
-v -classpath"${project_loc}/bin/classes"-d"${project_loc}/jni"${java_type_name}
--------------------------------------------
${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改为:
packagecom.lc.testndk2;
importjava.util.Arrays;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.widget.TextView;
publicclassMainActivityextendsActivity {
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv =newTextView(this);
int[] array =newint[] {1,2,3};
String str ="数组,调用C++前"+ Arrays.toString(array);
booleanisCopyOfArrayInCpp = NativeClass.jniArrayAdd(array,1);
str +="\n在C&
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。