新建一个android项目,同样生成native方法,然后选择项目右键->AndroidTools->Add
Native Supprot…..(前提是eclipse以安装ndk,并且要是ndkr7以上版本,不然就需要cygwin模仿linux环境,r7以后ndk封装了在linux环境,在windows能够使用)
执行后目录如下,产生了一个Android.mk文件和hellojni.cpp的c++文件
然后使用javah生成头文件,找到菜单栏的run->External Tools->External Tools Configurations 右键单击Program->New 定义一个名称,放入jdk下的javah路径 ,在工作空间选择本项目hellojni,加上-classpathsrc -d jni com.example.hellojni.MainActivity ,运行一下:
刷新项目目录在jni文件下就生成了相应的com_example_hellojni_MainActivity.hc++头文件:
在jni文件夹的hellojni.cpp中加如一行日志:
在jni->android.mk中添加:LOCAL_LDLIBS := -landroid -llog
然后Ctrl+B编译一下,回到java代码,在static中加载so文件,在oncreate()方法中调用obbnclick()方法,运行一下,在控制台打印出c++代码中的日志,ok
现在我们做一下改变,java端:声明两个String变量,让message显示setText()中
在jni->jnitest.cpp中修改一下,加入
//通过获取当前对象的jclass(env->GetObjectClass(obj))放入jfieldId中取得message对象
jfieldID fid_msg = env->GetFieldID(env->GetObjectClass(obj),"message","Ljava/lang/String;");
//获取messge的值
jstring j_msg = (jstring)env->GetObjectField(obj, fid_msg);
constjchar *jstr = env->GetStringChars(j_msg, NULL);
jfieldID fid_name = env->GetFieldID(env->GetObjectClass(obj),"name","Ljava/lang/String;");
jstring j_name = (jstring)env->GetObjectField(obj, fid_name);
constjchar *jstr_name=env->GetStringChars(j_name,NULL);
jobject j_newe_str = env->NewString(jstr_name,2);
//设置属性的值
env->SetObjectField(obj,fid_msg, j_newe_str);
现在在ctrl+B编译一下c++文件,然后再运行一遍android app就得到了以下结果,而不是hello:
Linux下生成so文件:
新建一个类,申明相应的native的类
package com.example.test;
public class test {
public native void a();
static{
System.loadLibrary("test");
}
}
保存终端到该项目的src目录下执行 javac com/example/test/test.java
将会在/src/com/example/test下生成相应的test.class文件
采用javah命令生成相应的头文件:javah com.example.test.test,这时候包是用.分隔且方法名没有后缀
将会生成com_example_test_test.h的头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_test_test */
#ifndef _Included_com_example_test_test
#define _Included_com_example_test_test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_test_test
* Method: a
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_test_test_a
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
然后新建一个com_example_test_test.cpp
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <stdio.h>
#include <com_example_test_test.h>
/* Header for class com_example_test_test */
extern "C"
/*
* Class: com_example_test_test
* Method: a
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_test_test_a
(JNIEnv * env, jobject obj*{
printf("HelloWorld JNI!\n");
}
这个时候对cpp文件用gcc动态编译成相应的so文件,此时采用的是linux的openJDK,导入相应的参数-I采用绝对路径:
gcc -shared -I /usr/lib/jvm/jdk1.6.0_45/include -I /usr/lib/jvm/jdk1.6.0_45/include/linux com_example_test_test.cpp -o libtest.so
com_example_test_test.cpp:4:35: 致命错误: com_example_test_test.h:没有那个文件或目录
执行命令后发现出现了相应的错误,是没有安装g++,所以安装g++等一些依赖的东西
sudo apt-get install build-essential
sudo apt-get install g++
然后在次执行 gcc -shared -I /usr/lib/jvm/jdk1.6.0_45/include -I /usr/lib/jvm/jdk1.6.0_45/include/linux com_example_test_test.cpp -o libtest.so
便生成了相应的libtest.so文件
然后加入编译路径,在代码中掉用a()方法