因为接触到一个项目,需要使用android代码读写底层的串口(实际上就是dev目录下的一个文件,linux系统一切皆文件),所以第一次接触到Android的java程序调用c++代码的问题。百度搜集的blog都说ndk7以上就自带了cygwin,因此这样省去了大量的环境配置时间。
其实java调用c/c++代码,是先把c++代码编译成一个动态链接库.so,然后通过一个接口文件,去调用里面的函数。好处就是可以直接操作部分硬件,也可以跨平台(ios可以直接调用c++代码),对代码的安全性也会更好。
自己下载android-ndk-r8,解压之后通过eclipse->Window->PReferences,点击Android下的NDK,把改目录导入即可。该目录下会有sample,但是我自己将jni例子导入工程的时候,提示找不到工程文件,也不知道怎么回事。。。,于是乎,就参考其它blog自己开始做了一个hello-jni的例子,其中还遇见不少麻烦事情。
首先创建android工程之后,点击项目属性,Android Tools->Add Native Support…,这时候会自动添加jni目录,包括Android.mk文件,和相应的一个cpp文件。Android.mk不需要做修改。
如果是cpp文件,需要添加extern “C”将java需要调用的方法包住,如果没添加,会导致程序出现闪退。同时需要注意文件中方法的命名方法 Java-包名-含对应jni方法的java类名-函数名
#include <jni.h>#include <string.h>extern "C"{ jstring Java_com_example_justjni_MainActivity_NDKTestFromJNI(JNIEnv* env,jobject thiz) { return env->NewStringUTF("Hello from JNI !"); }}接下来是对应的界面,包括了需要调用的jni方法。
public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText(NDKTestFromJNI()); setContentView(tv); } public native String NDKTestFromJNI();// native声明,表示这个方法来自Native层。实现过程已经在native层实现了 static { System.loadLibrary("justjni");// 加载库,前面的lib和后缀名不用写 }}最后就是编译运行,先在c++视角中编译生成一个动态链接库,生成成功会在libs/armeabi目录,java程序加载该动态库的时候,需要去掉前缀lib和文件名后缀.so,这里即”justjni”。最后直接编译运行生成apk文件,即可看到Android界面收到c++代码返回的字符串。
Eclipse报错“Unresolved inclusion jni.h”
最终的解决办法就是初始化eclipse对该project的nativesupport:
在eclipse中关闭指定Project
用其他编辑工具打开该project的.project文件,删除以下内容:
…… org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, ……
org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder full,incremental, …… org.eclipse.cdt.core.cnature org.eclipse.cdt.core.ccnature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
删除.cproject文件
在eclipse里打开原来的project, refresh,然后右键->properties->Android Tools -> Add Native Support
搞定
window平台下 Eclipse Ndk开发中的Method ‘NewStringUTF’ could not be resolved问题
项目右键->属性->c/c++常规->Code Analysis,选择Use project settings 中的方法无法被解析(Method cannot be resolved)取消选择,应用->确定,然后刷新、清理、刷新、build项目。
jni/hellocpp/main.cpp:16:18:error: base Operand of ‘->’ has non-pointer type ‘JNIEnv {aka _JNIEnv}’
错误在于:
(*env)->NewStringUTF(env, Hello from JNI !);
这一行,这是c的写法,而我的是cpp程序,需要改写成:
env->NewStringUTF( Hello from JNI !);
java.lang.UnsatisfiedLinkError:Native method not found问题 1、c++中的方法Java_xxx_xxx中的Java 首字母一定要大写
2、如果是 .cpp 文件则用 extern C {您的方法在这里},大括号里是您的本地方法。
参考blog1 Android串口编程参考blog
新闻热点
疑难解答